ホームページ  >  記事  >  ウェブフロントエンド  >  es6コールバック地獄とは何ですか?

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

青灯夜游
青灯夜游オリジナル
2023-02-14 14:58:541902ブラウズ

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 までご連絡ください。