1.指定回調函數的方式更加靈活:
舊的: 必須在啟動異步任務前指定
promise: 啟動異步任務 => 傳回promie對象 => 給promise對象綁定回調函數(甚至可以在異步任務結束後指定)
假設現在有一個名為 createAudioFileAsync() 的函數,如果給出一些配置和兩個回調函數,這個函數能異步地生成音頻檔案。一個回調函數是檔案成功建立時的回調,另一個則是出現異常時的回調。
- 不使用Promise,回調函數必須先指定
// 成功的回調函數
function successCallback (result) {
console.log('聲音檔案建立成功: ' + result)
}
// 失敗的回調函數
function failureCallback (error) {
console.log('聲音檔案建立失敗: ' + error)
}
/* 1.1 使用純回調函數 */
createAudioFileAsync(audioSettings, successCallback, failureCallback)
- 使用Promise
const promise = createAudioFileAsync(audioSettings)
promise.then(successCallback, failureCallback)
// 可簡寫為
createAudioFileAsync(audioSettings).then(successCallback, failureCallback);
可以在異步操作完成後再指定回調函數
setTimeout(() => {
promise.then(successCallback, failureCallback)
}, 3000)
- 回調地獄
doSomething(function (result) {
doSomethingElse(result, function (newResult) {
doThirdThing(newResult, function (finalResult) {
console.log('Got the final result: ' + finalResult)
}, failureCallback)
}, failureCallback)
}, failureCallback)
- 使用promise的鍊式調用解決回調地獄
doSomething().then(function (result) {
return doSomethingElse(result)
})
.then(function (newResult) {
return doThirdThing(newResult)
})
.then(function (finalResult) {
console.log('Got the final result: ' + finalResult)
})
.catch(failureCallback)
======
// 箭頭函數寫法
doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => {
console.log(`Got the final result: ${finalResult}`)
})
.catch(failureCallback)
- async/await: 回調地獄的終極解決方案
async function request () {
try {
const result = await doSomething()
const newResult = await doSomethingElse(result)
const finalResult = await doThirdThing(newResult)
console.log('Got the final result: ' + finalResult)
} catch (error) {
failureCallback(error)
}
}
- 無法取消
,一旦建立它就會立即執行,無法中途取消。Promise
- 如果不設定回調函數,
内部抛出的錯誤,不會反應到外部。Promise
- 當處于
狀态時,無法得知目前進展到哪一個階段(剛剛開始還是即将完成)pending
const someAsyncThing = function() {
return new Promise(function(resolve, reject) {
// 下面一行會報錯,因為x沒有聲明
resolve(x + 2);
});
};
someAsyncThing().then(function() {
console.log('everything is great');
});
setTimeout(() => { console.log(123) }, 2000);
// Uncaught (in promise) ReferenceError: x is not defined
// 123