1. 程式人生 > >Javascript關於promise的學習和執行時機

Javascript關於promise的學習和執行時機

Promise 的含義

所謂Promise,簡單說就是一個容器,裡面儲存著某個未來才會結束的事件(通常是一個非同步操作)的結果。從語法上說,Promise 是一個物件,從它可以獲取非同步操作的訊息。Promise 提供統一的 API,各種非同步操作都可以用同樣的方法進行處理。

Promise物件有以下兩個特點。

(1)物件的狀態不受外界影響。Promise物件代表一個非同步操作,有三種狀態:Pending(進行中)、Resolved(已完成,又稱 Fulfilled)和Rejected(已失敗)。只有非同步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。這也是Promise這個名字的由來,它的英語意思就是“承諾”,表示其他手段無法改變。

(2)一旦狀態改變,就不會再變,任何時候都可以得到這個結果。Promise物件的狀態改變,只有兩種可能:從Pending變為Resolved和從Pending變為Rejected。只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果。如果改變已經發生了,你再對Promise物件添加回調函式,也會立即得到這個結果。這與事件(Event)完全不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的。

有了Promise物件,就可以將非同步操作以同步操作的流程表達出來,避免了層層巢狀的回撥函式。此外,Promise物件提供統一的介面,使得控制非同步操作更加容易。

Promise也有一些缺點。首先,無法取消Promise,一旦新建它就會立即執行,無法中途取消。其次,如果不設定回撥函式,Promise內部丟擲的錯誤,不會反應到外部。第三,當處於Pending狀態時,無法得知目前進展到哪一個階段(剛剛開始還是即將完成)。

基本用法

最基本的用法

//Promise新建後就會立即執行。
var promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 非同步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});
//Promise例項生成以後,可以用then方法分別指定Resolved狀態和Reject狀態的回撥函式。
promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

還有很多用法,可以參考es6的相關資料

Promise.resolve()

有時需要將現有物件轉為Promise物件,Promise.resolve方法就起到這個作用。

Promise.resolve()有四種寫法:
1、如果引數是Promise例項,那麼Promise.resolve將不做任何修改、原封不動地返回這個例項。
2、thenable物件指的是具有then方法的物件,然後就立即執行thenable物件的then方法。
3、如果引數是一個原始值,或者是一個不具有then方法的物件,則Promise.resolve方法返回一個新的Promise物件,狀態為Resolved。
4、Promise.resolve方法允許呼叫時不帶引數,直接返回一個Resolved狀態的Promise物件。

promise和setTimeout的執行時間

例項如下:

setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');

// one
// two
// three

上面程式碼中,setTimeout(fn, 0)在下一輪“事件迴圈”開始時執行,Promise.resolve()在本輪“事件迴圈”結束時執行,console.log(’one‘)則是立即執行,因此最先輸出。