目次
#1. コールバック地獄とは何ですか? " >#1. コールバック地獄とは何ですか?
2. コールバック地獄を解決する方法" >2. コールバック地獄を解決する方法
1.Promise" >1.Promise
ホームページ ウェブフロントエンド フロントエンドQ&A es6コールバック地獄とは何ですか?

es6コールバック地獄とは何ですか?

Feb 14, 2023 pm 02:58 PM
es6 コールバック地獄

es6 では、コールバック ヘルは、互いにネストされた多層コールバック関数、つまり、コールバック関数内にネストされたコールバック関数です。これは、コードの順次実行を実現するために発生する操作であり、コードは非常に読みにくく、後で保守するのが困難です。 Promise はコールバック地獄の問題を解決するために es6 で使用されています。

es6コールバック地獄とは何ですか?

このチュートリアルの動作環境: Windows 7 システム、ECMAScript バージョン 6、Dell G3 コンピューター。

##序文

#「コールバック地獄」を正式に理解する前に、まず 2 つの概念を理解します。

1.コールバック関数

関数がパラメータとして別のパラメータに渡され、すぐには実行されない場合、その関数は特定の条件が満たされた場合にのみ実行されます。この種の関数はコールバックと呼ばれます。 。私たちがよく知っているタイマーと Ajax にはコールバック関数があります。

setTimeout(function(){   //function(){console.log('执行了回调函数')}就是回调函数,它只有在3秒后才会执行
	console.log('执行了回调函数');
},3000)  //3000毫秒
ログイン後にコピー
ここでのコールバック関数は

function(){console.log('コールバック関数が実行されました')} です。 , in 3秒後に実行します。

//1.创建异步对象
			var xhr=new XMLHttpRequest();
      //2.绑定监听事件(接收请求)
			xhr.onreadystatechange=function(){
				//此方法会被调用4次
				//最后一次,readyState==4
				//并且响应状态码为200时,才是我们要的响应结果 xhr.status==200
				if(xhr.readyState==4 && xhr.status==200){
					//把响应数据存储到变量result中
					var result=xhr.responseText;
					console.log(result);
				}
			}
      //3.打开链接(创建请求)
			xhr.open("get","/demo/ajaxDemo",true);
      //4.发送请求
			xhr.send();
ログイン後にコピー
ここでのコールバック関数は、

xhr.onreadystatechange にバインドされた関数で、xhr.send() がリクエストを送信し、レスポンスを取得した後に実行されます。

2. 非同期タスク

対応する概念は「同期タスク」です。同期タスクはメインスレッドで実行するためにキューに入れられ、前のタスクのみが実行されます。次のタスクを実行します。非同期タスクはメインスレッドには入りませんが、非同期キューに入ります。前のタスクが完了したかどうかは次のタスクの実行には影響しません。同様に、非同期タスクの例としてタイマーを取り上げます。

setTimeout(function(){
    console.log('执行了回调函数');
},3000)
console.log('111');
ログイン後にコピー

コードの記述順序に従うと、最初に「コールバック関数の実行」が出力され、次に「111」が出力されるはずです。ただし、実際の出力は次のようになります。


es6コールバック地獄とは何ですか? 後続のタスクの実行をブロックしないこの種のタスクは、非同期タスクと呼ばれます。

次に、コールバック地獄とは何かを見てみましょう。

#1. コールバック地獄とは何ですか?

上記に基づいて、結論を導き出すことができます: 非同期タスク用のコードがあり、順番に実行されることが保証されていません。では、コードを順番に実行する必要がある場合はどうすればよいでしょうか?

たとえば、文章を言いたい場合、語順は次のようにする必要があります。武道では、平和は尊重されるべきであり、武道倫理は尊重されるべきであり、いかなる戦いも避けるべきではありません。

順序が正しいことを確認するためにこれを行う必要があります:

        setTimeout(function () {  //第一层
            console.log('武林要以和为贵');
            setTimeout(function () {  //第二程
                console.log('要讲武德');
                setTimeout(function () {   //第三层
                    console.log('不要搞窝里斗');
                }, 1000)
            }, 2000)
        }, 3000)
ログイン後にコピー

es6コールバック地獄とは何ですか?

コード内のコールバック関数が 3 つの層にネストされていることがわかります。コールバック関数内にコールバック関数が入れ子になることをコールバック地獄と呼びます。

要約すると、コールバック 地獄は、コードを順次実行するために発生する操作であり、コードの可読性が非常に低くなり、後のメンテナンスが困難になります。

それでは、コールバック地獄を解決するにはどうすればよいでしょうか?

2. コールバック地獄を解決する方法

1.Promise

Promise は js にありますネイティブ オブジェクトは、従来のコールバック関数ソリューションを置き換えることができる非同期プログラミングのソリューションです。

  • Promise コンストラクターは関数をパラメーターとして受け取ります。処理する必要がある非同期タスクは関数本体にアンロードされます。関数の 2 つのパラメーターは、resolve と拒否です。非同期タスクが正常に実行されると、resolve 関数が呼び出されて結果が返されます。そうでない場合は、reject が呼び出されます。

  • Promise オブジェクトの then メソッドは、処理が成功した場合の応答データの受信に使用され、catch メソッドは処理が失敗した場合の対応するデータの受信に使用されます。

  • Promise のチェーン プログラミングでは、コードの実行順序を保証できます。前提として、以降の処理のたびに、Promise オブジェクトが返され、次の時点で受信できるようにする必要があります。次はデータ。

次はコード例です:

        function fn(str){
            var p=new Promise(function(resolve,reject){
                //处理异步任务
                var flag=true;
                setTimeout(function(){
                    if(flag){
                        resolve(str)
                    }
                    else{
                        reject('操作失败')
                    }
                })
            })
            return p;
        }

        fn('武林要以和为贵')
        .then((data)=>{
            console.log(data);
            return fn('要讲武德');
        })
        .then((data)=>{
            console.log(data);
            return fn('不要搞窝里斗')
        })
        .then((data)=>{
            console.log(data);
        })
        .catch((data)=>{
            console.log(data);
        })
ログイン後にコピー

es6コールバック地獄とは何ですか? しかし、Promise の最大の問題はコードの冗長性です。元の非同期タスクは Promise によってカプセル化されます。 、「すべての操作に対してよりを使用」に関係なく、一見したところ、すべてが「then...then...then...」という結果になり、コードのメンテナンスには役立ちません。

したがって、次の async/await コードは同期コードに似ています。

2.async/await

最初に、

async キーワードを見ていきます。 is 宣言された関数の前にキーワードが配置され、関数が非同期タスクであり、後続の関数の実行をブロックしないことを示します。

        async function fn(){
            return '不讲武德';
        }
        console.log(fn());
ログイン後にコピー

es6コールバック地獄とは何ですか? async を実行すると、それがわかります。関数がデータを返すと、それは自動的に Promise オブジェクトにカプセル化されます。

Promise オブジェクトと同様に、非同期タスクの処理でも成功時と失敗時に異なるデータを返すことができ、処理が成功した場合は then メソッドで受け取り、失敗した場合は catch を使用します。データを受信するメソッド:

        async function fn() {
            var flag = true;
            if (flag) {
                return '不讲武德';
            }
            else{
                throw '处理失败'
            }
        }
        fn()
        .then(data=>{
            console.log(data);
        })
        .catch(data=>{
            console.log(data);
        })

        console.log('先执行我,表明async声明的函数是异步的');
ログイン後にコピー

es6コールバック地獄とは何ですか?
当把flag设置为false是,执行结果为:
es6コールバック地獄とは何ですか?
async关键字说完了,我们看看awai关键字

  • await关键字只能在使用async定义的函数中使用
  • await后面可以直接跟一个 Promise实例对象(可以跟任何表达式,更多的是跟一个返回Promise对象的表达式)
  • await函数不能单独使用
  • await可以直接拿到Promise中resolve中的数据。
        //封装一个返回promise的异步任务
        function fn(str) {
            var p = new Promise(function (resolve, reject) {
                var flag = true;
                setTimeout(function () {
                    if (flag) {
                        resolve(str)
                    } else {
                        reject('处理失败')
                    }
                })
            })
            return p;
        }

        //封装一个执行上述异步任务的async函数
        async function test(){
            var res1=await fn('武林要以和为贵');  //await直接拿到fn()返回的promise的数据,并且赋值给res
            var res2=await fn('要讲武德');
            var res3=await fn('不要搞窝里斗');
            console.log(res1,res2,res3);
        }
        //执行函数
        test();
ログイン後にコピー

结果为:
es6コールバック地獄とは何ですか?
为什么叫await等待呢,因为当代码执行到async函数中的await时,代码就在此处等待不继续往下执行,知道await拿到Promise对象中resolve的数据,才继续往下执行,这样就保证了代码的执行顺序,而且使异步代码看起来更像同步代码。

总结

总结一下,当我们写代码遇到异步回调时,我们想让异步代码按照我们想要的顺序执行,如果按照传统的嵌套方式,就会出现回调地狱,这样的代码不利于维护,我们可以通过Promise对象进行链式编程来解决,这样尽管可以解决问题,但是ES7给我们提供了更加舒适的async/await语法糖,可以使得异步代码看起来更像是同步代码。

【相关推荐:javascript视频教程web前端

以上がes6コールバック地獄とは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

非同期は es6 または es7 用ですか? 非同期は es6 または es7 用ですか? Jan 29, 2023 pm 05:36 PM

非同期はes7です。 async と await は ES7 に新しく追加されたもので、非同期操作のソリューションです。async/await は co モジュールとジェネレーター関数の糖衣構文と言え、より明確なセマンティクスで JS 非同期コードを解決します。名前が示すように、async は「非同期」を意味します。async は関数が非同期であることを宣言するために使用されます。async と await の間には厳密な規則があります。両方を互いに分離することはできず、await は async 関数内でのみ記述できます。

ES6 で配列を反転する方法 ES6 で配列を反転する方法 Oct 26, 2022 pm 06:19 PM

ES6 では、配列オブジェクトの reverse() メソッドを使用して、配列の反転を実現できます。このメソッドは、配列内の要素の順序を逆にして、最後の要素を最初に、最初の要素を最後に配置するために使用されます。構文「array」 。逆行する()"。 reverse() メソッドは元の配列を変更します。変更したくない場合は、拡張演算子 "..." とともに使用する必要があり、構文は "[...array].reverse() 」。

es6 の 2 つの配列で異なる項目を見つける方法 es6 の 2 つの配列で異なる項目を見つける方法 Nov 01, 2022 pm 06:07 PM

手順: 1. 構文 "newA=new Set(a); newB=new Set(b);" を使用して、2 つの配列をそれぞれセット型に変換します; 2. has() と filter() を使用して差分セットを検索します、構文 " new Set([...newA].filter(x =>!newB.has(x)))" では、差分セット要素がセット コレクションに含まれて返されます。 3. 配列を使用します。 from セットを配列に変換するタイプ、構文は「Array.from(collection)」です。

ミニ プログラムで es6 を es5 に変換する必要があるのはなぜですか? ミニ プログラムで es6 を es5 に変換する必要があるのはなぜですか? Nov 21, 2022 pm 06:15 PM

ブラウザの互換性のため。 ES6 は JS の新しい仕様として、多くの新しい構文と API を追加していますが、最新のブラウザーは ES6 の新機能を高度にサポートしていないため、ES6 コードを ES5 コードに変換する必要があります。 WeChat Web 開発者ツールでは、デフォルトで babel が使用され、開発者の ES6 構文コードを 3 つの端末すべてで適切にサポートされる ES5 コードに変換し、開発者がさまざまな環境によって引き起こされる開発上の問題を解決できるようにします。プロジェクト内でのみ設定して確認するだけです。 「ES6~ES5」オプション。

es5 および es6 で配列重複排除を実装する方法 es5 および es6 で配列重複排除を実装する方法 Jan 16, 2023 pm 05:09 PM

es5 では、for ステートメントと IndexOf() 関数を使用して配列の重複排除を実現できます。構文 "for(i=0;i<配列長;i++){a=newArr.indexOf(arr[i]);if( a== -1){...}}」。 es6 では、スプレッド演算子 Array.from() および Set を使用して重複を削除できます。まず配列を Set オブジェクトに変換して重複を削除してから、スプレッド演算子または Array.from() 関数を使用する必要があります。 Set オブジェクトを配列に変換してグループ化するだけです。

es6 の一時的なデッドゾーンとは何を意味しますか? es6 の一時的なデッドゾーンとは何を意味しますか? Jan 03, 2023 pm 03:56 PM

es6 では、一時的なデッド ゾーンは構文エラーであり、ブロックを閉じたスコープにする let および const コマンドを指します。コード ブロック内では、let/const コマンドを使用して変数が宣言される前に、変数は使用できず、変数が宣言される前は変数の「デッド ゾーン」に属します。これは構文上「一時デッド ゾーン」と呼ばれます。 ES6 では、一時的なデッド ゾーンや let ステートメントや const ステートメントでは変数のプロモーションが発生しないことを規定しています。これは主に実行時エラーを減らし、変数が宣言される前に使用されて予期しない動作が発生するのを防ぐためです。

es6 構文が必要ですか? es6 構文が必要ですか? Oct 21, 2022 pm 04:09 PM

いいえ、require は CommonJS 仕様のモジュール構文であり、es6 仕様のモジュール構文は import です。 require は実行時にロードされ、import はコンパイル時にロードされます。require はコード内のどこにでも記述できます。import はファイルの先頭にのみ記述でき、条件文や関数スコープでは使用できません。モジュール属性は導入されるだけです。 require を実行した場合、そのためパフォーマンスは比較的低くなりますが、インポート コンパイル中に導入されたモジュールのプロパティのパフォーマンスはわずかに高くなります。

es6 マップは注文されていますか? es6 マップは注文されていますか? Nov 03, 2022 pm 07:05 PM

地図は注文済みです。 ES6 のマップ タイプは、多くのキーと値のペアを格納する順序付きリストです。キー名と対応する値はすべてのデータ型をサポートします。キー名の等価性は、「Objext.is()」メソッドを呼び出すことによって決定されます。 , したがって、数字の 5 と文字列「5」は 2 つのタイプとして判断され、プログラム内で 2 つの独立したキーとして現れることができます。

See all articles