JavaScript中的promise使用

promise初始

Promise 是異步編程的一種解決方案,Promise 能夠認爲是一個對象,從它能夠獲取異步操做的消息。Promise 提供統一的 API,各類異步操做均可以用一樣的方法進行處理。具備兩大特色:編程

  1. 對象的狀態不受外界影響。Promise對象表明一個異步操做,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗),只有promise執行的結果能夠影響當前狀態,不管是異步操做仍是同步操做。
  2. 一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。Promise對象的狀態改變,只有兩種可能:從pending變爲fulfilled和從pending變爲rejected。

基本用法

ES6 規定,Promise對象是一個構造函數,用來生成Promise實例。json

new Promise(
    /* executor */
    function(resolve, reject) {...}
);

Promise構造函數接受一個函數做爲參數,該函數的兩個參數分別是resolve和reject。它們是兩個函數,由 JavaScript 引擎提供,不用本身部署。看一個實例:promise

let promise = new Promise(function(resolve, reject) {
  console.log('Promise');
  resolve();
});

promise.then(function() {
  console.log('resolved.');
});

console.log('Hi!');

// Promise
// Hi!
// resolved

能夠看到,在new promise的時候,會當即執行promise構造函數中的參數function,也就是包含resolve、reject兩個方法的函數會被當即執行,上面代碼中,Promise 新建後當即執行,因此首先輸出的是Promise。而後,then方法指定的回調函數,將在當前腳本全部同步任務執行完纔會執行,因此resolved最後輸出。
注意:
1. promise的參數函數中若是resolve、reject這兩個函數中的某個帶了參數也是 promise的話,那麼這個本來的promise的狀態將會由參數中的promise的狀態決定
2. resolve、reject並不會想return同樣結束函數的運行異步

then方法

then方法是定義在原型對象Promise.prototype上的。它的做用是爲 Promise 實例添加狀態改變時的回調函數。then方法的第一個參數是resolved狀態的回調函數,第二個參數(可選)是rejected狀態的回調函數。then方法返回的是一個新的Promise實例(注意,不是原來那個Promise實例)。所以能夠採用鏈式寫法,即then方法後面再調用另外一個then方法。異步編程

// getJSON 是一個promise實例
getJSON("/posts.json").then(function(json) {
  return json.post;
}).then(function(post) {
  // ...
});

不少時候在then中會人爲的書寫一些異步操做,這樣能夠很好的鏈式調用,可是即便不是人爲的異步操做,JavaScript也會自動的把then的返回值封裝爲promise實例,能夠一直使用then無限回調。函數

catch方法

Promise.prototype.catch方法是.then(null, rejection)的別名,用於指定發生錯誤時的回調函數。若是異步操做拋出錯誤,狀態就會變爲rejected,就會調用catch方法指定的回調函數,處理這個錯誤。另外,then方法指定的回調函數,若是運行中拋出錯誤,也會被catch方法捕獲。post

//getJSON 是一個promise
getJSON('/posts.json').then(function(posts) {
  // ...
}).catch(function(error) {
  // 處理 getJSON 和 前一個回調函數運行時發生的錯誤
  console.log('發生錯誤!', error);
});

比較推薦的書寫方法是先使用then來給promise添加resolve的回調,而後使用catch來捕獲全部的連接上的reject或者異常。prototype

promise.resolve理解

能夠說Promise.resolve是惟一的把promise轉換爲完成狀態的操做,Promise.resolve方法的參數分紅四種狀況:code

  1. 參數是一個promise實例
    若是參數是Promise實例,那麼Promise.resolve將不作任何修改、原封不動地返回這個實例。這個以前已經說過了,若是promise的的resolve參數帶的是一個promise,那麼本來promise的將會被丟棄,由這個新的promise的狀態來取代
  2. 參數是一個thenable對象
    thenable對象指的是具備then方法的對象,Promise.resolve方法會將這個對象轉爲Promise對象,而後就當即執行thenable對象的then方法。
  3. 參數不是具備then方法的對象,或根本就不是對象
    若是參數是一個原始值,或者是一個不具備then方法的對象,則Promise.resolve方法返回一個新的Promise對象,狀態爲resolved。
  4. 不帶有任何參數
    Promise.resolve方法容許調用時不帶參數,直接返回一個resolved狀態的Promise對象。

promise.reject理解

Promise.reject(reason)方法也會返回一個新的 Promise 實例,該實例的狀態爲rejected。
注意,Promise.reject()方法的參數,會原封不動地做爲reject的理由,變成後續方法的參數。這一點與Promise.resolve方法不一致。對象

其餘

  1. done()
    Promise對象的回調鏈,無論以then方法或catch方法結尾,要是最後一個方法拋出錯誤,都有可能沒法捕捉到(由於Promise內部的錯誤不會冒泡到全局)。所以,咱們能夠提供一個done方法,老是處於回調鏈的尾端,保證拋出任何可能出現的錯誤。
  2. done() finally方法用於指定無論Promise對象最後狀態如何,都會執行的操做。它與done方法的最大區別,它接受一個普通的回調函數做爲參數,該函數無論怎樣都必須執行。
相關文章
相關標籤/搜索