2016-08-03 35 views
11

我觀察到的是,在下面的代碼:無極VS的setTimeout

setTimeout(function(){console.log('setTimeout')}); 
Promise.resolve(1).then(function(){console.log('promise resolve')}) 

不管我多少次執行此,許回調總是setTimeout的前記錄。

我的理解是,這兩個回調計劃執行到下一個滴答聲,我真的不明白是怎麼回事,這使得承諾總是超過超時。

+3

'Promise'一旦創建就獲得'resolved',而'setTimeout'後來在隊列中。 – Rayon

+1

閱讀內部隊列/事件循環:https://developer.mozilla.org/en -US/docs/Web/JavaScript/EventLoop,http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/或觀看此視頻:https://www.youtube.com/watch?v = 8aGhZQkoFbQ –

回答

4

簡答答案在事件循環堆棧中(或者我是怎麼理解的)Promise的優先級比setTimeout的回調函數要好。

長時間回答觀看此視頻。很有幫助。希望這可以幫助。

https://www.youtube.com/watch?v=8aGhZQkoFbQ

+0

好視頻:)謝謝 –

0

超時和承諾服務於不同的目的。

setTimeout將代碼塊的執行延遲了特定的持續時間。 Promise是允許異步執行代碼的接口。

promise允許代碼在等待另一個操作完成時繼續執行。通常這是一個網絡電話。因此,一旦網絡呼叫(或任何承諾等待)完成,您的then()呼叫中的任何內容都將被執行。承諾的開始和承諾的解決之間的時間差異完全取決於承諾正在執行的內容,並且可以隨着每次執行而改變。

承諾在超時之前執行的原因是承諾並未實際等待任何事情,因此它立即解決。

+2

由此邏輯,在此代碼中:'Promise.resolve(2).then(function(){console.log('promise resolve 2')}); console.log('立即')'「承諾解決2」會記錄在「立即」之前嗎?但它沒有 – frankies

+3

@frankies這與Promises排隊和解決的方式有關。我的答案的重點是'setTimeout'和'Promise'之間的區別。 – jfadich

9

setTimeout()minimum delay of 4ms,所以即使你沒有指定代碼中的延遲超時仍將至少4毫秒延遲。您的承諾.then()在此期間被調用。

+0

即使沒有4ms節流優化,承諾反正會更快。因爲'setTimeout'創建任務,'Promise'創建微任務(工作)。這是真正的原因。 – Artin

+1

嗯......好的,但實際上4ms最小*不適用,所以在宏與微任務優先級沒有進入的問題中就是這樣的例子。如果我們想象不同於實際實現的行爲,那麼即使承諾的優先級低於超時,示例中的承諾仍會首先記錄,因爲最小超時時間爲4ms。儘管如此,回到現實世界中,知道JS中存在微觀任務概念非常有用,所以感謝提及它。 – nnnnnn

5

Promise.resolve安排一個微任務,setTimeout安排一個macrotask。在運行下一個macrotask之前執行微任務。

+2

這是最接近的答案。我會添加鏈接以深入解釋任務/ microtasks。 https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ – Artin

+1

同樣值得一提的是,微任務的來源可能只有兩件事:MutationObserver和Promises。 – Artin