92. setTimeout、Promise、Async/Await 的差別?
setTimeout
// 1. 列印 script start
console.log('script start')
// 2. 調用 setTimeout 函數, 并定義其完成後執行的回調函數
setTimeout(function () {
// 4. 列印 settimeout
console.log('settimeout')
})
// 3. 列印 script start
console.log('script end')
// 輸出順序:script start->script end->settimeout
Promise
Promise
本身是同步的立即執行函數, 當在
executor
中執行
resolve
或者
reject
的時候, 此時是異步操作, 會先執行
then/catch
等, 當主棧完成後, 才會去調用
resolve/reject
中存放的方法執行, 列印
p
的時候, 是列印的傳回結果, 一個
Promise
執行個體。
console.log('script start')
let promise1 = new Promise(function (resolve) {
console.log('promise1')
resolve()
console.log('promise1 end')
}).then(function () {
console.log('promise2')
})
setTimeout(function () {
console.log('settimeout')
})
console.log('script end')
// 輸出順序: script start->promise1->promise1 end->script end->promise2->settimeout
當
JS
主線程執行到
Promise
對象時:
-
的回調就是一個promise1.then()
task
-
是promise1
或resolved
: 那這個rejected
就會放入目前事件循環回合的task
microtask queue
-
是promise1
: 這個pending
就會放入 事件循環的未來的某個(可能下一個)回合的task
中microtask queue
-
的回調也是個setTimeout
, 它會被放入task
即使是macrotask queue
的情況0ms
async/await
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2() {
console.log('async2')
}
console.log('script start');
async1();
console.log('script end')
// 輸出順序:script start->async1 start->async2->script end->async1 end
async
函數傳回一個
Promise
對象, 當函數執行的時候, 一旦遇到
await
就會先傳回, 等到觸發的異步操作完成, 再執行函數體内後面的語句。可以了解為, 是讓出了線程, 跳出了
async
函數體。
例如:
async function func1() {
return 1
}
console.log(func1())
func1
的運作結果其實就是一個
Promise
對象。是以也可以使用
then
來處理後續邏輯。
func1().then(res => {
console.log(res); // 30
})
await
的含義為等待, 也就是
async
函數需要等待
await
後的函數執行完成并且有了傳回結果(
Promise
對象)之後, 才能繼續執行下面的代碼。
await
通過傳回一個
Promise
對象來實作同步的效果。