ホームページ > 記事 > ウェブフロントエンド > es6コールバック地獄とは何ですか?
es6 では、コールバック ヘルは、互いにネストされた多層コールバック関数、つまり、コールバック関数内にネストされたコールバック関数です。これは、コードの順次実行を実現するために発生する操作であり、コードは非常に読みにくく、後で保守するのが困難です。 Promise はコールバック地獄の問題を解決するために es6 で使用されています。
このチュートリアルの動作環境: Windows 7 システム、ECMAScript バージョン 6、Dell G3 コンピューター。
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」が出力されるはずです。ただし、実際の出力は次のようになります。
後続のタスクの実行をブロックしないこの種のタスクは、非同期タスクと呼ばれます。
順序が正しいことを確認するためにこれを行う必要があります:
setTimeout(function () { //第一层 console.log('武林要以和为贵'); setTimeout(function () { //第二程 console.log('要讲武德'); setTimeout(function () { //第三层 console.log('不要搞窝里斗'); }, 1000) }, 2000) }, 3000)コード内のコールバック関数が 3 つの層にネストされていることがわかります。コールバック関数内にコールバック関数が入れ子になることをコールバック地獄と呼びます。 要約すると、コールバック 地獄は、コードを順次実行するために発生する操作であり、コードの可読性が非常に低くなり、後のメンテナンスが困難になります。 それでは、コールバック地獄を解決するにはどうすればよいでしょうか?
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); })
しかし、Promise の最大の問題はコードの冗長性です。元の非同期タスクは Promise によってカプセル化されます。 、「すべての操作に対してよりを使用」に関係なく、一見したところ、すべてが「then...then...then...」という結果になり、コードのメンテナンスには役立ちません。
async キーワードを見ていきます。 is 宣言された関数の前にキーワードが配置され、関数が非同期タスクであり、後続の関数の実行をブロックしないことを示します。
async function fn(){ return '不讲武德'; } console.log(fn());
async を実行すると、それがわかります。関数がデータを返すと、それは自動的に Promise オブジェクトにカプセル化されます。
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声明的函数是异步的');
当把flag设置为false是,执行结果为:async
关键字说完了,我们看看awai
关键字
//封装一个返回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();
结果为:
为什么叫await
等待呢,因为当代码执行到async
函数中的await
时,代码就在此处等待不继续往下执行,知道await
拿到Promise对象中resolve的数据,才继续往下执行,这样就保证了代码的执行顺序,而且使异步代码看起来更像同步代码。
总结一下,当我们写代码遇到异步回调时,我们想让异步代码按照我们想要的顺序执行,如果按照传统的嵌套方式,就会出现回调地狱,这样的代码不利于维护,我们可以通过Promise对象进行链式编程来解决,这样尽管可以解决问题,但是ES7给我们提供了更加舒适的async/await语法糖,可以使得异步代码看起来更像是同步代码。
【相关推荐:javascript视频教程、web前端】
以上がes6コールバック地獄とは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。