首頁 >web前端 >js教程 >js面試過程中遇到的非同步問題

js面試過程中遇到的非同步問題

王林
王林轉載
2020-09-19 17:42:202599瀏覽

js面試過程中遇到的非同步問題

js中的巨集任務與微任務

(推薦教學:js教學

在面試過程中,基本面試官都會問你一些promise的問題,promise是es6的新內容,主要是用來優化非同步的問題。筆試中常常會讓你寫一些promise和setTimeout的執行結果,這你就必須知道宏任務和微任務的概念了!

為什麼要使用promise

如果你經歷過以前的jquery開發項目,你會遇到以下問題:回呼地獄

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

原因分析:

ajax請求嵌套,原因是我第二個請求依賴的參數在第一個請求的結果中,所以就得這麼一直嵌套下去,ajax是異步的,不能再外面拿到裡面的結果。這種程式碼導致的問題就是調試困難,耦合性非常高,後期改動一個地方就頭痛!維護非常困難,程式碼可讀性差。
於是乎就引入了promise對ajax進行了優化,axios就是基於promise的一個請求封裝庫,他們底層都是基於js原生的XMLHTTPREQUEST.
promise().then().catch()鏈式調用,多個請求可以promise().then().then()。

何為巨集任務,何為微任務?

思考這個問題時你必須知道javascript是一種單執行緒的腳本語言,也就是它的程式碼正常只能從上往下依序執行,一次只能做一件事,非同步是透過回呼函數來實現的。為何不把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 and await中的執行順序

程式碼如下(範例):

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是單執行緒語言,它的用途決定了他的特性,非同步操作通過事件循環機制,先執行同步程式碼,然後微任務,最後宏任務,兩個任務佇列裡的任務排隊依序執行。 await後面的程式碼必須等待promise回傳結果再執行下面程式碼,await和async是generator函數的語法糖。

以上是js面試過程中遇到的非同步問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除