国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

promise

jay_tian / 2049人閱讀

摘要:是一個對象,它的內(nèi)部其實有三種狀態(tài)。已拒絕的異步操作未成功結束。方法則是將對象的狀態(tài)改變?yōu)槭。瑫r將錯誤的信息傳遞到后續(xù)錯誤處理的操作。在第二個中拿到數(shù)據(jù)并且捕獲。使用的寫法比一般的寫法更加清晰明確。

## 前言

今天來分享下promise的用法,es6偉大發(fā)明之一,當初我學習的時候也是蠻頭大的,不知道為啥,整個腦子就是,我在哪,我要干啥的懵圈,后面認真學習之后,覺得真是十分好用,下面就來一起學習下吧。

為什么會有promise

首先為什么會有promise的存在,其實很多人都知道的,其中最大的問題就是在處理多個有依賴關系的異步操作時,會出現(xiàn)回調(diào)地獄( callback hell ),如下:

$.ajax({
      url:?"....",
      success:?function?(data)?{
            $.ajax({
                  url:?"....",
                  success:?function?(data)?{
              }
          });
      }
 });

promise提供了一個優(yōu)雅的方式,來解決這個問題,同時提供了很多的錯誤捕獲機制。

如何使用promise

我們先不講promise的理論語法,這樣會一開始就降低學習的欲望,直接來看使用案例,然后去理解。

首先看基本使用
new Promise(function (resolve, reject) {
         // 假設此處是異步請求某個數(shù)據(jù)
               $.ajax({
                  url:?"......",
                   success:?function?(res)?{
                       if (res.code === 200) {
                            resolve(res.data);
                        } else {
                           reject("獲取data失敗");
                      }
                   }
               })
})
.then(function A(data) {
        // 成功,下一步
      console.log( data);
 }, function B(error) {
        // 失敗,做相應處理
       console.log(error)
 });
console:
sucess
error

解析:

梳理流程:

首先我們在promise函數(shù)里,執(zhí)行我們的異步操作得到data

如果成功的話,通過resolve函數(shù)數(shù)據(jù)傳遞出來,如果失敗。通過reject把錯誤信息傳遞出來

然后在.then里可以接受傳遞出來的數(shù)據(jù),.then()里面接受兩個函數(shù),第一個函數(shù)接收resolve傳遞出來的值,也就是正確情況下的處理,第二個函數(shù)接收reject傳遞的信息,也就是錯誤的情況下的處理。

Promise是一個對象,它的內(nèi)部其實有三種狀態(tài)。

初始狀態(tài)( pending )。

已完成( fulfilled ): Promise 的異步操作已結束成功。

已拒絕( rejected ): Promise 的異步操作未成功結束。

resolve 方法可以使 Promise 對象的狀態(tài)改變成成功,同時傳遞一個參數(shù)用于后續(xù)成功后的操作。
reject 方法則是將 Promise 對象的狀態(tài)改變?yōu)槭。瑫r將錯誤的信息傳遞到后續(xù)錯誤處理的操作。

then(onFulfilled, onRejected)

---(onFulfilled, onRejected)

鏈式then

當然,我們既然解決回調(diào)地獄,一個異步,看不出來啥優(yōu)勢,現(xiàn)在看多個異步請求, 為了代碼簡約,我們用setTimeout來代替ajax請求 作為異步操作,如下:

new Promise((resolve, reject) => {
     setTimeout( () => {
          if (...){
            resolve([1, 2, 3])
        } else {
            reject("error");
        }
   }, 2000);
})
 .then( data => {
        console.log(value);  // 打印出[1, 2, 3]
        return new Promise( (resolve, reject)=> {   // 新的異步請求,需要promise對象
            let data2 = 1 + data;
            setTimeout( () => {
              if (...) {
                   resolve(data2);
              } else {
                  reject("error2")
              }
              
            }, 2000);
       });
  }, error => {
      cosnole.log(error)
  })
.then( data2 => {
      console.log(data2 );
 }, error => {
      cosnole.log(error)
  });
解析:

-這個例子中,第一個異步操作得到數(shù)據(jù)[1, 2, 3],傳遞到第一個then中,我們在第一個then中運用拿到的數(shù)據(jù),進行第二次異步操作,并把結果傳遞出去。在第二個then中拿到數(shù)據(jù),并且捕獲error。
可以看到本來嵌套的兩個異步操作,現(xiàn)在清晰多了,而且鏈式接無數(shù)個then

在這里有兩個地方需要注意

then里面的可捕獲錯誤的函數(shù),可以捕獲到上面的所有then的錯誤,所以只在最后一個then里,寫錯誤捕獲函數(shù)就可以。

每次異步操作時候需要返回一個新的promise,因為只有用promise對象才會等異步操作執(zhí)行完,才去執(zhí)行下面的then,才能拿到異步執(zhí)行后的數(shù)據(jù),所以第二個then里的異步請求,也需要聲明Promise對象。如果then里面返回常量,可以直接返回。如下:

new Promise((resolve, reject) => {
     setTimeout( () => {
          if (...){
            resolve([1, 2, 3])
        } else {
            reject("error");
        }
   }, 2000);
})
 .then( value => {
        return "222";    // 如果是直接返回常量,可直接return
    })
 .then( value2 => {
     console.log(value2 ); // 打印出222
 })

下面忽略error情況,看兩個例子,大家可以自己思考下打印結果

new Promise(resolve => {
    setTimeout( () => {
        resolve("value1");
    }, 2000);
})
 .then( value1 => {
        console.log(value1);
        (function () {
            return new Promise(resolve => {
                setTimeout(() => {
                    console.log("Mr.Laurence");
                    resolve("Merry Xmas");
                }, 2000);
            });
        }());
        return false;
    })
 .then( value => {
     console.log(value + " world");
 });

value1
false world
Mr.Laurence
new Promise( resolve => {
    console.log("Step 1");
    setTimeout(() => {
        resolve(100);
    }, 1000);
})
.then( value => {
     return new Promise(resolve => {
         console.log("Step 1-1");
         setTimeout(() => {
            resolve(110);
         }, 1000);
    })
    .then( value => {
           console.log("Step 1-2");
           return value;
    })
   .then( value => {
         console.log("Step 1-3");
         return value;
    });
})
.then(value => {
      console.log(value);
      console.log("Step 2");
});

console:
Step 1
Step 1-1
Step 1-2
Step 1-3
110
Step 2
catch

catch 方法是 then(onFulfilled, onRejected) 方法當中 onRejected 函數(shù)的一個簡單的寫法,也就是說可以寫成 then(fn).catch(fn),相當于 then(fn).then(null, fn)。使用 catch 的寫法比一般的寫法更加清晰明確。我們在捕獲錯誤的時候,直接在最后寫catch函數(shù)即可。

 let promise = new Promise(function(resolve, reject) {
    throw new Error("Explosion!");
});
promise.catch(function(error) {
      console.log(error.message); // "Explosion!"
});

上面代碼等于與下面的代碼

 let promise = new Promise(function(resolve, reject) {
    throw new Error("Explosion!");
});
promise.catch(function(error) {
      console.log(error.message); // "Explosion!"
});
異步代碼錯誤拋出要用reject
new Promise( resolve => {
    setTimeout( () => {
        throw new Error("bye");
    }, 2000);
})
.then( value => {
 })
.catch( error => {
      console.log( "catch", error);
 });
控制臺會直接報錯 Uncaught Error: bye

解析:因為異步情況下,catch已經(jīng)執(zhí)行完了,錯誤才拋出,所以無法捕獲,所以要用reject,如下:

new Promise( (resolve, reject) => {
    setTimeout( () => {
        reject("bye");
    }, 2000);
})
.then( value => {
        console.log( value + " world");
 })
.catch( error => {
      console.log( "catch", error);
 });

catch bye
利用reject可以抓捕到promise里throw的錯
catch 可以捕獲then里丟出來的錯,且按順序只抓捕第一個沒有被捕獲的錯誤
new Promise( resolve => {
    setTimeout( () => {
        resolve();
    }, 2000);
})
.then( value => {
    throw new Error("bye");
 })
.then( value => {
   throw new Error("bye2");
 })
.catch( error => {
  console.log( "catch", error);
 });

console: Error: bye
new Promise( resolve => {
    setTimeout( () => {
        resolve();
    }, 2000);
})
.then( value => {
    throw new Error("bye");
 })
.catch( error => {
  console.log( "catch", error);
 })
.then( value => {
   throw new Error("bye2");
 })
.catch( error => {
  console.log( "catch", error);
 });

console: Error: bye
console: Error: bye2
catch 抓捕到的是第一個沒有被捕獲的錯誤
錯誤被捕獲后,下面代碼可以繼續(xù)執(zhí)行
new Promise(resolve => {
    setTimeout(() => {
        resolve();
    }, 1000);
})
    .then( () => {
        throw new Error("test1 error");
    })
    .catch( err => {
        console.log("I catch:", err);   // 此處捕獲了 "test1 error",當錯誤被捕獲后,下面代碼可以繼續(xù)執(zhí)行
    })
    .then( () => {
        console.log(" here");
    })
    .then( () => {
        console.log("and here");
         throw new Error("test2 error");
    })
    .catch( err => {
        console.log("No, I catch:", err);  // 此處捕獲了 "test2 error"
    });

I catch: Error: test2 error
here
and here
 I catch: Error: test2 error
錯誤在捕獲之前的代碼不會執(zhí)行
new Promise(resolve => {
    setTimeout(() => {
        resolve();
    }, 1000);
})
    .then( () => {
        throw new Error("test1 error");
    })
    .catch( err => {
       console.log("I catch:", err);   // 此處捕獲了 "test1 error",不影響下面的代碼執(zhí)行
       throw new Error("another error"); // 在catch里面丟出錯誤,會直接跳到下一個能被捕獲的地方。
    })
    .then( () => {
        console.log("and here");
         throw new Error("test2 error");
    })
    .catch( err => {
        console.log("No, I catch:", err);  // 此處捕獲了 "test2 error"
    });

I catch: Error: test2 error
I catch: Error: another error
new Promise(resolve => {
    setTimeout(() => {
        resolve();
    }, 1000);
})
    .then( () => {
        console.log("start");
        throw new Error("test1 error");
    })
    .then( () => {
        console.log("arrive here");
    })
    .then( () => {
        console.log("... and here");
         throw new Error("test2 error");  
    })
    .catch( err => {
        console.log("No, I catch:", err);   // 捕獲到了第一個
    });

No, I catch: Error: test1 error
    at Promise.then (:8:1
Promise.all
Promise.all([1, 2, 3])
      .then( all => {
          console.log("1:", all);
      })
[1, 2, 3]
Promise.all([function () {console.log("ooxx");}, "xxoo", false])
      .then( all => {
         console.log( all);
      });
?[?, "xxoo", false]
let p1 = new Promise( resolve => {
            setTimeout(() => {
                resolve("I"m P1");
            }, 1500);
});
let p2 = new Promise( (resolve, reject) => {
            setTimeout(() => {
                resolve("I"m P2");
            }, 1000);
 });
let p3 = new Promise( (resolve, reject) => {
            setTimeout(() => {
                resolve("I"m P3");
            }, 3000);
 });

 Promise.all([p1, p2, p3]).then( all => {
       console.log("all", all);
}).catch( err => {
        console.log("Catch:", err);
});

all (3)?["I"m P1", "I"m P2", "I"m P3"]
案例:刪除所有數(shù)據(jù)后,做一些事情、、、、
db.allDocs({include_docs: true}).then(function (result) {
  return Promise.all(result.rows.map(function (row) {
    return db.remove(row.doc);
  }));
}).then(function (arrayOfResults) {
  // All docs have really been removed() now!
});
Promise.resolve
Promise.resolve()
    .then( () => {
        console.log("Step 1");
    })
其他
Promise.resolve("foo").then(Promise.resolve("bar")).then(function (result) {
  console.log(result);
});
VM95:2 foo
如果你向 then() 傳遞的并非是一個函數(shù)(比如 promise)
它實際上會將其解釋為 then(null),這就會導致前一個 promise 的結果會穿透下面
How do I gain access to resultA here?
function getExample() {
    return promiseA(…).then(function(resultA) {
        // Some processing
        return promiseB(…);
    }).then(function(resultB) {
        // More processing
        return // How do I gain access to resultA here?
    });
}
解決 Break the chain
function getExample() {
    var a = promiseA(…);
    var b = a.then(function(resultA) {
        // some processing
        return promiseB(…);
    });
    return Promise.all([a, b]).then(function([resultA, resultB]) {
        // more processing
        return // something using both resultA and resultB
    });
}

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/102205.html

相關文章

  • Promise的幾個擴展API總結

    摘要:的幾個擴展總結描述和相反,當所有的被拒絕之后,方法執(zhí)行完成的決議,如果存在一個執(zhí)行完成的決議,方法則執(zhí)行拒絕里邊的所有實例反過來就好了執(zhí)行到此執(zhí)行到此描述忽略被拒絕的,只需要有一個完成的,方法就執(zhí)行完成操作,如果全部的都被拒絕,方法執(zhí)行拒絕 Promise的幾個擴展API總結 1. Promise.none 描述: 和 Promise.all 相反,當所有的promise被拒絕之后,n...

    李義 評論0 收藏0
  • Promise 中的三兄弟 .all(), .race(), .allSettled()

    摘要:對于的來說基元函數(shù)包括組合函數(shù)的類型簽名返回情況完成如果傳入的可迭代對象為空,會同步地返回一個已完成狀態(tài)的。相反,如果是在指定的時間之后完成,剛返回結果就是一個拒絕狀態(tài)的從而觸發(fā)方法指定的回調(diào)函數(shù)。在行中,對每個小任務得到的結果進行匯總。 為了保證的可讀性,本文采用意譯而非直譯。 想閱讀更多優(yōu)質(zhì)文章請猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 從ES6 開始,我們大都使用的是 P...

    vspiders 評論0 收藏0
  • 異步發(fā)展流程 —— 手寫一個符合 Promise/A+ 規(guī)范的 Promise

    摘要:構造函數(shù)的實現(xiàn)我們在使用的時候其實是使用關鍵字創(chuàng)建了一個的實例,其實是一個類,即構造函數(shù),下面來實現(xiàn)構造函數(shù)。 showImg(https://segmentfault.com/img/remote/1460000018998456); 閱讀原文 概述 Promise 是 js 異步編程的一種解決方案,避免了 回調(diào)地獄 給編程帶來的麻煩,在 ES6 中成為了標準,這篇文章重點不是敘...

    UnixAgain 評論0 收藏0
  • 實現(xiàn)Promise

    摘要:使用是極好的,它是如此有用以至于我覺得應該好好研究一下,甚至是實現(xiàn)一個簡易的版本。構造函數(shù)檢查參數(shù)例如是不是函數(shù)啊初始化,創(chuàng)建對象執(zhí)行因此構造函數(shù)里面?zhèn)魅氲氖橇⒓幢粓?zhí)行的。 使用Promise是極好的,它是如此有用以至于我覺得應該好好研究一下Promise,甚至是實現(xiàn)一個簡易的版本。實現(xiàn)之前,我們先來看看Promise的用途: 使用Promise callback hell Promi...

    xcc3641 評論0 收藏0
  • Promise 對象的理解

    摘要:使用對象的好處在于可以將異步操作以同步操作的流程表達出來,避免了層層嵌套的回調(diào)函數(shù)。對象異步操作拋出錯誤,狀態(tài)就會變?yōu)椋蜁{(diào)用方法指定的回調(diào)函數(shù)處理這個錯誤。 Promise 含義 Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強大。它由社區(qū)最早提出和實現(xiàn),ES6 將其寫進了語言標準,統(tǒng)一了用法,原生提供了 Promise 對象。 所謂 P...

    church 評論0 收藏0
  • Promise的源碼實現(xiàn)(完美符合Promise/A+規(guī)范)

    摘要:以上代碼,可以完美通過所有用例。在的函數(shù)中,為何需要這個同樣是因為規(guī)范中明確表示因此我們需要這樣的來確保只會執(zhí)行一次。其他情況,直接返回以該值為成功狀態(tài)的對象。 Promise是前端面試中的高頻問題,我作為面試官的時候,問Promise的概率超過90%,據(jù)我所知,大多數(shù)公司,都會問一些關于Promise的問題。如果你能根據(jù)PromiseA+的規(guī)范,寫出符合規(guī)范的源碼,那么我想,對于面試...

    gaomysion 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<