jsインタビューの質問の非同期質問

jsのマクロタスクとマイクロタスク

インタビュー中に、基本的なインタビュアーがプロミスについていくつか質問します。プロミスはes6の新しいコンテンツであり、主に非同期問題を最適化するために使用されます。書かれたテストでは、promiseとsetTimeoutの実行結果について書くように求められることが多いので、マクロタスクとマイクロタスクの概念を知っておく必要があります。


プロミスを使う理由

以前のjquery開発プロジェクトを経験したことがある場合は、次の問題が発生します:コールバック地獄

$.ajax({
    
    
	...
	success: function() {
    
    
		...
		$.ajax({
    
    
			...
			success: function() {
    
    
				
			}
		})
		...
	}
})

原因分析:

Ajaxリクエストはネストされています。理由は、2番目のリクエストが依存するパラメーターが最初のリクエストの結果に含まれるため、常にネストする必要があるためです。Ajaxは非同期であり、内部で結果を取得できません。この種のコードによって引き起こされる問題は、デバッグが難しく、カップリングが非常に高いことです。後で場所を変更するのは頭痛の種です!メンテナンスは非常に難しく、コードは読みにくいです。
そこで、Ajaxを最適化するためのpromiseを紹介しました。Axiosはpromiseに基づくリクエストカプセル化ライブラリです。その最下層はjsネイティブXMLHTTPREQUESTに基づいています。Promise
()。then()。catch()チェーン呼び出し、複数のリクエストあなたはpromise()。then()。then()をすることができます。


マクロタスクとマイクロタスクとは何ですか?

この問題について考えるとき、javascriptはシングルスレッドのスクリプト言語であること、つまり、そのコードは上から下に順番にしか実行できず、一度に1つしか実行できないことを知っておく必要があります。非同期は、コールバック関数によって実現されます。jsをマルチスレッド言語として設計しないのはなぜですか?言語の目的によって言語の特性が決まります。jsは当初、フォームの検証と定期的な判断、およびDOM要素の操作に使用されていました。jsに複数のスレッドがある場合、一方がDOM要素の変更を実行し、もう一方が削除を実行すると、ブラウザが気絶します。どうすればよいですか?したがって、言語の目的によって言語の特性が決まりますが、ブラウザはマルチスレッド化されており、メインスレッド以外にも他のスレッドがあります。

jsメインプログラムが実行されると、メインプログラムの同期コードが最初に実行され、setTimeoutまたはsetIntervalが検出されると、マクロキューに配置され、promiseコールバックが検出されると、マイクロキューに配置されます。プログラムは、最初にメインプログラムを実行します。コード、次にnextTickコード、次にマイクロタスク、最後にマクロタスクを実行します。タスクキューは実行のために順番にキューに入れられ、asyncとawaitが一緒に使用され、awaitの後にpromiseオブジェクトが続きます。次のコードを見てみましょう。

 setTimeout(function(){
    
    console.log(1)},0);  // 进入宏任务队列,最后执行宏任务
 new Promise(function(resolve,reject){
    
    
     console.log(2); //这句代码在promise构造器,同步执行
     resolve(); // 执行了resolve再把任务放入微队列
 }).then(function(){
    
    console.log(3)
 }).then(function(){
    
    console.log(4)});
 process.nextTick(function(){
    
    console.log(5)});
 console.log(6); // 主程序代码
 // 输出2,6,5,3,4,1
 
// 下面这个进阶代码
setTimeout(function(){
    
    console.log(1)},0); // 进入宏任务排序为1
new Promise(function(resolve,reject){
    
    
     console.log(2);
     // promise中执行完resolve()才会执行then(),而这里的resolve在宏任务里,执行完主程序代码后,还得先执行先进入宏队列中的程序
     setTimeout(function(){
    
    resolve()},0) // 进入宏任务排序为2
 }).then(function(){
    
    console.log(3)
 }).then(function(){
    
    console.log(4)});
 process.nextTick(function(){
    
    console.log(5)});
 console.log(6);
 // 输出的是  2 6 5 1 3 4

非同期で実行順序を確認して待ちます

コードは次のとおりです(例):

async function async1() {
    
    
    console.log(1); 
    await async2();
    console.log(2); //这里要等await执行成功才会执行,进入微任务,排序1
}
async function async2() {
    
    
    console.log(3);
}
console.log(4); //主程序代码
setTimeout(function() {
    
    
    console.log(5);
}, 0) //进入宏任务,最后执行
async1();
new Promise(function(resolve) {
    
    
    console.log(6); // 这句同步执行
    resolve(); 
}).then(function() {
    
    
    console.log(7); //进入微任务,排序2
});
console.log(8); // 主程序代码
// 输出的是  4,1,3,6,8,2,7,5

総括する

jsはシングルスレッド言語であり、その使用法はその特性を決定します。非同期操作は、イベントループメカニズムを使用して、最初に同期コードを実行し、次にマイクロタスクを実行し、最後にマクロタスクを実行します。2つのタスクキューのタスクは順番にキューに入れられ、実行されます。awaitの背後にあるコードは、次のコードを実行する前にpromiseが戻るのを待つ必要があります。awaitとasyncは、ジェネレーター関数の構文シュガーです。

おすすめ

転載: blog.csdn.net/qq_42671194/article/details/108660748