天天看點

為什麼要使用Promise,Promise的優點

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      

繼續閱讀