Promise學習:基礎入門

今天來學習下Promise吧,其實這在筆試上也是一個考點.javascript

基本介紹

Promise對象是CommonJS(熟悉的名字吧- -)工做組提出的規範.Promise本來只是社區提出的構想,一些外部函數庫率先實現了該功能,ES6中將其寫入了語言標準.
目的:爲異步操做提供統一接口java

Promise是啥,它就是一個javascript中一個對象,起着代理做用,充當異步操做與回調函數之間的中介.
避免相似於
clipboard.pngajax

這種嵌套地獄的產生.讓咱們的代碼變得更加簡單易讀
使用了Promise,你們都說好json

(new Promise(f1).then(f2));

總結:Promise使得異步操做的向下發展變成橫向發展,程序流程變得清晰,易於閱讀.數組

基本思想

  • 異步任務返回一個Promise對象,它有三種狀態promise

    • pending(未完成)異步

    • resolved,fulfilled(已完成)ide

    • rejected(失敗)函數

  • 它有兩種變化途徑工具

    • pending --> resolved/fulfilled

    • pending --> rejected

  • 它有兩種結果

    • 異步操做成功,返回一個值,狀態變爲resolved

    • 異步操做失敗,拋出一個錯誤,狀態變爲rejected

Promise使用.then()方法添加回調函數,then接收兩個回調函數,第一個爲成功時的回調函數,另外一個爲失敗時的回調函數.主要爲狀態改變時調用相對的回調函數.
並且then能夠鏈式調用.

基本使用

Promise構造函數接受一個函數做爲參數,而該函數兩個參數分別是resolvereject.它們由JS引擎提供,不須要本身部署.

Promise(function(resolve,reject){})

resolve函數做用爲:將Promise對象從未完成變爲成功(Pending->Resolved),異步操做成功時調用,並將異步操做的結果做爲參數傳遞出去.
reject函數做用爲:將Promise對象從未完成變爲失敗(Pending->Rejected),異步操做失敗時調用,並將異步操做報出的錯誤做爲參數傳遞出去.


Promise.then()方法能夠用於指定Resolved狀態和Reject狀態的回調函數.

promise.then(function(value){//成功+_+!},function(value){//失敗Q_Q});

咱們只想對異常進行處理時能夠採用promise.then(undefined, onRejected)這種方式,或者promise.catch(onRejected)
!注意!此處有坑,接下來在深刻節會進行講解


Promise.all()方法接收一個promise對象的數組爲參數,當這個數組中全部的Promise對象所有變成resolve/reject狀態的時候,纔會調用.then方法,其中傳入的promise是同時開始,並行執行的.

promise.all([promise1,promise2,.....]);

Promise.race()方法和Promise.all()方法同樣接收一個promise對象的數組做爲參數,可是數組中有一個promise對象進入fulfilled或rejected狀態,就會開始後續處理.

promise.race([promise1,promise2,.....]);

相關的語法糖

Promise.resolve(42);
//等價於
new Promise(function(resolve){
    resolve(42);
});

Promise.reject(new Error("出錯了"));
//等價於
new Promise(function(resolve,reject){
    reject(new Error("出錯了"));
});

深刻

關於Thenable對象

這是很是相似於Promise的東西,擁有.then方法.
其中比較經典的例子就是jQuery.ajax()返回的值就是thenable的.

var promise = Promise.resolve($.ajax('/json/comment.json'));

這樣就能夠將thenable對象轉化爲promise對象
傳送門:Promise.resolve()

關於promise設計:老是異步操做

看代碼就能明白這個地方的問題了.

var promise = new Promise(function (resolve){
    console.log("inner promise"); // 1
    resolve(42);
});
promise.then(function(value){
    console.log(value); // 3
});
console.log("outer promise"); // 2
//結果是
/*
inner promise // 1
outer promise // 2
42            // 3
*/

能夠看出,即便咱們調用promise.then時promise對象已經肯定狀態,Promise也會以異步的方式調用回調函數,這就是Promise設計上的規定方針.

關於調用then/catch

每次調用then/catch,都會返回一個promise對象,這一點上咱們經過使用===就能夠判斷出來每次promise對象其實都是不同的

then和catch的錯誤處理區別

這點和上一點聯合起來很容易理解
直接上圖吧,來自於JavaScript Promise迷你書(中文版)

clipboard.png

在結合咱們的代碼吧

// <1> onRejected不會被調用
function badMain(onRejected) {
    return Promise.resolve(42).then(throwError, onRejected);
}
// <2> 有異常發生時onRejected會被調用
function goodMain(onRejected) {
    return Promise.resolve(42).then(throwError).catch(onRejected);
}

onFullfilled中發生的錯誤,如在<1>裏面throwError中的錯誤,是不會致使onRejected的執行(捕獲異常)的,咱們只能經過後面的catch方法才能捕獲.

基本應用

不兼容方面

  1. 不兼容就是用polyfill

  2. 關於IE8以及如下版本中,catch會因爲在ES3中爲保留字,致使identifier not found錯誤,對此咱們能夠經過["catch"]或者then(undefined,function(){})來進行catch,而某些類庫中,採用了caught做爲函數名來規避該問題.值得注意的是,有不少壓縮工具中自帶了.catch轉["catch"]

應用示例:
加載圖片

var preloadImage = function(path){
  return new Promise(function(resolve,reject){
    var image = new Image();
    image.onload = resolve;
    image.onerror = reject;
    image.src = path;
  })
}
preloadImage("https://dn-anything-about-doc.qbox.me/teacher/QianDuan.png").then(function(){
  alert("圖片加載成功");
},function(){
  alert("圖片加載失敗");
})

Ajax操做

function search(term) {
    var url = 'http://example.com/search?q=' + term;
    var xhr = new XMLHttpRequest();
    var result;
    var p = new Promise(function(resolve, reject) {
        xhr.open('GET', url, true);
        xhr.onload = function(e) {
            if (this.status === 200) {
                result = JSON.parse(this.responseText);
                resolve(result);
            }
        };
        xhr.onerror = function(e) {
            reject(e);
        };
        xhr.send();
    });
    return p;
}
search("Hello World").then(console.log, console.error);

回到最初吧,其實Promise對象優勢仍是在於規範的鏈式調用,能夠清晰看出程序流程.而且對於錯誤還能定義統一的處理方法.

相關文章
相關標籤/搜索