Promise
同步和異步:
同步:一件事做完了才到另一件事(與現(xiàn)實(shí)中的同步相反)
異步:在做一件事請(qǐng)枝恋,這件事還沒(méi)做完就開(kāi)始做另一件事(有一段時(shí)間同時(shí)做兩件事)
異步是非阻塞的创倔,異步邏輯與主邏輯相互獨(dú)立,主邏輯不需要等待異步邏輯完成焚碌,而是可以立即繼續(xù)下去畦攘。怎么理解呢?就是可能有一件事卡住了做不了十电,但是不影響其他事情繼續(xù)下去知押。
所謂 Promise,就是一個(gè)對(duì)象鹃骂,用來(lái)傳遞異步操作的消息台盯。它代表了某個(gè)未來(lái)才會(huì)知道結(jié)果的事件(通常是一個(gè)異步操作),并且這個(gè)事件提供統(tǒng)一的 API畏线,可供進(jìn)一步處理静盅。
new Promise((resolve,reject) => {
setTimeout(()=>{
resolve("異步請(qǐng)求成功的數(shù)據(jù)"); //如果請(qǐng)求成功則把參數(shù)傳遞給then
reject("異步請(qǐng)求失敗了"); //如果請(qǐng)求失敗則把參數(shù)傳遞給catch
},1000)})
.then((data) => { //接收傳輸?shù)臄?shù)據(jù)
console.log(data); //處理數(shù)據(jù)
})
.catch((err) => { //接收請(qǐng)求失敗的數(shù)據(jù)
console.log(err); //處理
})
.finally((all) => {
console.log(all);
})
.then返回的是一個(gè)promise實(shí)例,所以可以進(jìn)行鏈?zhǔn)秸{(diào)用寝殴。
Promise.all
可以將多個(gè)Promise實(shí)例包裝成一個(gè)新的Promise實(shí)例蒿叠。同時(shí),成功和失敗返回值是不同的蚣常,全部成功時(shí)返回的是結(jié)果數(shù)組市咽,有一個(gè)失敗則返回最先失敗的的promise結(jié)果。
Promise.all([p1,p2,p3...]).then(...)
Promise.all([
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("第一個(gè)請(qǐng)求");
},1000)
}),
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("第二個(gè)請(qǐng)求");
},2000)
})
]).then((result)=>{
console.log(result[0]);
console.log(result[1]);
})
Promise.race
顧名思義race就是賽跑的意思抵蚊,跟Promise.all差不多施绎,只不過(guò)是就返回那個(gè)最先完成的結(jié)果溯革,不管那個(gè)結(jié)果是成功還是失敗。
Async / await
也是用來(lái)處理異步谷醉,其實(shí)是Generator函數(shù)的改進(jìn)致稀,背后原理就是Promise
async
async function f1(){
return "abc"
}
/*
async 自動(dòng)包裝成Promise對(duì)象,等價(jià)于
function f1(){
return new Promise((resolve) => {resolve("abc")})
}
*/
await
await只能放在async函數(shù)里面
async function f1(){
return new Promise((resolve,reject) => {resolve("f1")})
}
async function f3(){
try {
var c = await f1();//下面的代碼阻塞孤紧,只有await完了才能繼續(xù)執(zhí)行
console.log(c);
} catch (error) {
console.log("error");//如果f1是reject豺裆,必須使用trycatch才能繼續(xù)執(zhí)行下面的代碼哦。
}finally{
}
console.log("執(zhí)行完了");
}
宏任務(wù)和微任務(wù)
宏任務(wù):script的整體代碼号显,setTimeout臭猜,setInterval,setImmediate
微任務(wù):promise.then押蚤,process.nextTick
js 是單線程執(zhí)行的蔑歌,js中的任務(wù)按順序一個(gè)一個(gè)的執(zhí)行,但是一個(gè)任務(wù)耗時(shí)太長(zhǎng)揽碘;
那么后面的任務(wù)就需要等待次屠,為了解決這種情況,將任務(wù)分為了同步任務(wù)和異步任務(wù)雳刺;
而異步任務(wù)又可以分為微任務(wù)和宏任務(wù)劫灶。
script代碼塊就是一個(gè)宏任務(wù),執(zhí)行一個(gè)宏任務(wù)掖桦,先執(zhí)行同步代碼本昏,遇到異步代碼(promise,setTimeout等)會(huì)讓他們進(jìn)行排隊(duì)枪汪,分別排兩條隊(duì)涌穆。一條是宏任務(wù)S,一條是微任務(wù)P雀久。執(zhí)行完同步任務(wù)后執(zhí)行微任務(wù)宿稀,同樣同步任務(wù)立即執(zhí)行,遇到異步任務(wù)進(jìn)行排隊(duì)赖捌。把全部微任務(wù)執(zhí)行完就執(zhí)行宏任務(wù)祝沸,宏任務(wù)執(zhí)行完一個(gè)就會(huì)去清理微任務(wù)隊(duì)列,所以在宏任務(wù)里面的微任務(wù)會(huì)比外面的宏任務(wù)先執(zhí)行越庇。
圖解:
舉個(gè)栗子: