2 回答

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超1個(gè)贊
Promise 構(gòu)造函數(shù)是完全同步的(除非你調(diào)用其他異步的東西,比如setTimeout
或另一個(gè) Promise)。在第二個(gè)代碼中,同步promiseFunction1
運(yùn)行并立即調(diào)用resolve
。對(duì)promiseFunction2
. 因此,創(chuàng)建的第一個(gè) Promise(這里是 from promiseFunction1
)將在第二個(gè)之前解決,無論每個(gè)promiseFunction
運(yùn)行的同步操作可能是昂貴的。
該promiseFunction1
承諾立即首先解析,如此這般到microtask隊(duì)列第一,那么其相關(guān)的.then
運(yùn)行第一。
昂貴的同步代碼通常不是在主線程上運(yùn)行的好主意,因?yàn)樗鼤?huì)阻塞 UI - 如果您遇到這種情況,請(qǐng)考慮將其移至工作線程,如果可能的話。
對(duì)于您的第一個(gè)代碼:
我當(dāng)時(shí)認(rèn)為每個(gè)承諾都是沒有順序保證的并行執(zhí)行。
因?yàn)?code>resolveAfter2Seconds2 秒后resolveAfter1Second
解析,1 秒后解析,所以幾乎可以保證 1 秒 Promise 將首先解析。
下面的兩個(gè)代碼是一樣的嗎?
一點(diǎn)也不。首先,promiseFunction
當(dāng)parallel
被調(diào)用時(shí),兩者都會(huì)立即運(yùn)行。在第二種情況下,promiseFunction2
僅在promiseFunction1
解決后運(yùn)行。

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超7個(gè)贊
說Promise鏈通常意味著一系列then()調(diào)用,明確地意圖按順序運(yùn)行它們,但是以異步方式,等待步驟之間的某些事件。
而不是編寫一系列深入的嵌套回調(diào)......
function delay2s(callback){
setTimeout(callback,2000);
}
delay2s(()=>{
log.innerText="1.";
delay2s(()=>{
log.innerText+=" 2.";
delay2s(()=>{
log.innerText+=" 3.";
delay2s(()=>{
log.innerText+=" 4.";
delay2s(()=>{
log.innerText+=" 5.";
delay2s(()=>{
log.innerText+=" and Done.";
});
});
});
});
});
});
<span id="log">Soon</span>
...你可以保持在一個(gè)“理智”的水平:
function delay2s(){
return new Promise(resolve=>setTimeout(()=>resolve(),2000));
}
delay2s().then(()=>{
log.innerText="1.";
return delay2s();
}).then(()=>{
log.innerText+=" 2.";
return delay2s();
}).then(()=>{
log.innerText+=" 3.";
return delay2s();
}).then(()=>{
log.innerText+=" 4.";
return delay2s();
}).then(()=>{
log.innerText+=" 5.";
return delay2s();
}).then(()=>{
log.innerText+=" and Done.";
});
<span id="log">Soon</span>
而且擁有多個(gè)獨(dú)立的Promises并不代表它們一起運(yùn)行,而是它們一起等待。
當(dāng)然,這種情況下也有一些不錯(cuò)的輔助工具。就像等待一些事件,并在所有事件都完成后做某事可能看起來像一些討厭的、命名的回調(diào)加上一些更討厭的計(jì)數(shù)器:
let counter=5;
function tryfinal(){
if(--counter>0)return;
log.innerText+=" all Done.";
}
for(let i=0;i<counter;i++){
setTimeout(()=>{
log.innerText=(log.innerText=="Soon"?"":log.innerText+" ")+(i+1)+".";
tryfinal();
},4000*Math.random());
}
<span id="log">Soon</span>
或者它可以使用Promise.all/Settled():
let promises=[];
for(let i=0;i<5;i++){
promises.push(new Promise(resolve=>setTimeout(()=>{
log.innerText=(log.innerText=="Soon"?"":log.innerText+" ")+(i+1)+".";
resolve();
},4000*Math.random())));
}
Promise.all(promises).then(()=>log.innerText+=" and Done.");
<span id="log">Soon</span>
如果你想積極地并行做一些事情,你需要線程,這意味著web workers。此示例在兩個(gè)線程上向上計(jì)數(shù)幾秒鐘,不時(shí)報(bào)告進(jìn)度(在此期間它與 CPU 一起烹飪,您可以檢查您所在操作系統(tǒng)的一些性能監(jiān)控應(yīng)用程序):
let limit=5000000000;
let report=100000000;
if(limit>Number.MAX_SAFE_INTEGER)
log.innerText="No, you do not want that.";
else {
let workertext="data:text/plain,"
+escape("for(let i=0;i<="+limit+";i++)"
+" if(i%"+report+"===0)"
+" postMessage(i);"
+"postMessage('Done');");
console.log(workertext);
let w1=new Worker(workertext);
let w2=new Worker(workertext);
w1.onmessage=m=>log1.innerText+=" "+m.data;
w2.onmessage=m=>log2.innerText+=" "+m.data;
}
<div id="log1">Worker1: </div>
<div id="log2">Worker2: </div>
旁注:有趣的是,在超出帶符號(hào)的 32 位整數(shù)范圍(日志中的 2100000000 -> 2200000000,或?qū)嶋H邊界為 2147483647 -> 2147483648)后,計(jì)數(shù)會(huì)變慢。至少在我的 Chrome 中。
添加回答
舉報(bào)