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

資訊專欄INFORMATION COLUMN

promise-then 深入理解異步

caozhijian / 754人閱讀

摘要:異步常用的幾種方式今天著重來講解一下和隊(duì)列有何關(guān)聯(lián)在這里我們需要先理解在應(yīng)用的過程中需要注意的地方一定要,或者出去不要,做副作用函數(shù)。拋出同步異常談到,這是讓更加贊的一點(diǎn)。再強(qiáng)調(diào)一次,這個(gè)函數(shù)并不需要關(guān)心這個(gè)異常是同步還是異步返回的。

異步常用的幾種方式

setTimeout/EventEmitter/Promise/generator/async-await 今天著重來講解一下 promise

setTimeout和Promise隊(duì)列有何關(guān)聯(lián)
setTimeout(function(){console.log(4)},0); 
new Promise(function(resolve){ 
    console.log(1) 
    for( var i=0 ; i<10000 ; i++ ){ i==9999 && resolve() } 
    console.log(2) })
.then(function(){ console.log(5) });
 console.log(3);
在這里我們需要先理解We have a problem with promises
    doSomething().then(function () {
      return doSomethingElse();
    });
    
    doSomething().then(function () {
      doSomethingElse();
    });
    
    doSomething().then(doSomethingElse());
    
    doSomething().then(doSomethingElse);
promise 在應(yīng)用的過程中需要注意的地方
1.new promise (resolve,reject){};一定要resolve,或者reject 出去不要,做副作用函數(shù)。
2.then 操作里面 接收 promise 對象,如果在promise里面是執(zhí)行的純函數(shù),也可以返回一個(gè) promise。resolve("常量")。避免promise 穿透
正確使用 promise 金字塔代碼

新手錯(cuò)誤 #1: promise版的金字塔問題
觀察大家如何使用 PouchDB 這類大型的 promise 風(fēng)格的API,我發(fā)現(xiàn)大量錯(cuò)誤的 promise 使用形式。最常見的錯(cuò)誤就是下面這個(gè):

remotedb.allDocs({
  include_docs: true,
  attachments: true
}).then(function (result) {
  var docs = result.rows;
  docs.forEach(function(element) {
    localdb.put(element.doc).then(function(response) {
      alert("Pulled doc with id " + element.doc._id + " and added to local db.");
    }).catch(function (err) {
      if (err.status == 409) {
        localdb.get(element.doc._id).then(function (resp) {
          localdb.remove(resp._id, resp._rev).then(function (resp) {

// et cetera...
是的,實(shí)際上你可以像使用回調(diào)一樣使用 promises,恩,就像用打磨機(jī)去削腳趾甲一樣,你確實(shí)可以這么做。

并且如果你以為這樣的錯(cuò)誤只限于初學(xué)者,那么你會驚訝于我實(shí)際上是在黑莓官方開發(fā)者博客上看到上面的代碼。老的回調(diào)風(fēng)格的習(xí)慣難以消滅。(至開發(fā)者: 抱歉選了你的例子,但是你的例子將會有積極的教育意義)

正確的風(fēng)格應(yīng)該是這樣:

remotedb.allDocs(...).then(function (resultOfAllDocs) {
  return localdb.put(...);
}).then(function (resultOfPut) {
  return localdb.get(...);
}).then(function (resultOfGet) {
  return localdb.put(...);
}).catch(function (err) {
  console.log(err);
});

這種寫法被稱為 composing promises ,是 promises 的強(qiáng)大能力之一。每一個(gè)函數(shù)只會在前一個(gè) promise 被調(diào)用并且完成回調(diào)后調(diào)用,并且這個(gè)函數(shù)會被前一個(gè) promise 的輸出調(diào)用,稍后我們在這塊做更多的討論。

4.promise 中foreach 操作,轉(zhuǎn)換成 promise.all()=>返回一個(gè)數(shù)組

5.在任何應(yīng)用到了promise的過程中,一定要注意使用catch 將異常拋出來,不然會堵塞整個(gè)加載

使用副作用調(diào)用而非返回

下面的代碼有什么問題?

somePromise().then(function () {
  someOtherPromise();
}).then(function () {
  // Gee, I hope someOtherPromise() has resolved!
  // Spoiler alert: it hasn"t.
});

好了,現(xiàn)在是時(shí)候討論一下關(guān)于 promises 你所需要知道的一切。

認(rèn)真的說,這是一個(gè)一旦你理解了它,就會避免所有我提及的錯(cuò)誤的古怪的技巧。你準(zhǔn)備好了么?

就如我前面所說,promises 的奇妙在于給予我們以前的 return 與 throw。但是在實(shí)踐中這到底是怎么一回事呢?

每一個(gè) promise 都會提供給你一個(gè) then() 函數(shù) (或是 catch(),實(shí)際上只是 then(null, ...) 的語法糖)。當(dāng)我們在 then() 函數(shù)內(nèi)部時(shí):

somePromise().then(function () {
  // I"m inside a then() function!
});

我們可以做什么呢?有三種事情:

return 另一個(gè) promise
return 一個(gè)同步的值 (或者 undefined)
throw 一個(gè)同步異常
就是這樣。一旦你理解了這個(gè)技巧,你就理解了 promises。因此讓我們逐個(gè)了解下。

返回另一個(gè) promise
這是一個(gè)在 promise 文檔中常見的使用模式,也就是我們在上文中提到的 “composing promises”:

getUserByName("nolan").then(function (user) {
  return getUserAccountById(user.id);
}).then(function (userAccount) {
  // I got a user account!
});

注意到我是 return 第二個(gè) promise,這個(gè) return 非常重要。如果我沒有寫 return,getUserAccountById() 就會成為一個(gè)副作用,并且下一個(gè)函數(shù)將會接收到 undefined 而非 userAccount。
返回一個(gè)同步值 (或者 undefined)
返回 undefined 通常是錯(cuò)誤的,但是返回一個(gè)同步值實(shí)際上是將同步代碼包裹為 promise 風(fēng)格代碼的一種非常贊的手段。舉例來說,我們對 users 信息有一個(gè)內(nèi)存緩存。我們可以這樣做:

getUserByName("nolan").then(function (user) {
  if (inMemoryCache[user.id]) {
    return inMemoryCache[user.id];    // returning a synchronous value!
  }
  return getUserAccountById(user.id); // returning a promise!
}).then(function (userAccount) {
  // I got a user account!
});

是不是很贊?第二個(gè)函數(shù)不需要關(guān)心 userAccount 是從同步方法還是異步方法中獲取的,并且第一個(gè)函數(shù)可以非常自由的返回一個(gè)同步或者異步值。

不幸的是,有一個(gè)不便的現(xiàn)實(shí)是在 JavaScript 中無返回值函數(shù)在技術(shù)上是返回 undefined,這就意味著當(dāng)你本意是返回某些值時(shí),你很容易會不經(jīng)意間引入副作用。

出于這個(gè)原因,我個(gè)人養(yǎng)成了在 then() 函數(shù)內(nèi)部 永遠(yuǎn)返回或拋出 的習(xí)慣。我建議你也這樣做。

拋出同步異常
談到 throw,這是讓 promises 更加贊的一點(diǎn)。比如我們希望在用戶已經(jīng)登出時(shí),拋出一個(gè)同步異常。這會非常簡單:

getUserByName("nolan").then(function (user) {
  if (user.isLoggedOut()) {
    throw new Error("user logged out!"); // throwing a synchronous error!
  }
  if (inMemoryCache[user.id]) {
    return inMemoryCache[user.id];       // returning a synchronous value!
  }
  return getUserAccountById(user.id);    // returning a promise!
}).then(function (userAccount) {
  // I got a user account!
}).catch(function (err) {
  // Boo, I got an error!
});

如果用戶已經(jīng)登出,我們的 catch() 會接收到一個(gè)同步異常,并且如果 后續(xù)的 promise 中出現(xiàn)異步異常,他也會接收到。再強(qiáng)調(diào)一次,這個(gè)函數(shù)并不需要關(guān)心這個(gè)異常是同步還是異步返回的。

這種特性非常有用,因此它能夠在開發(fā)過程中幫助定位代碼問題。舉例來說,如果在 then() 函數(shù)內(nèi)部中的任何地方,我們執(zhí)行 JSON.parse(),如果 JSON 格式是錯(cuò)誤的,那么它就會拋出一個(gè)異常。如果是使用回調(diào)風(fēng)格,這個(gè)錯(cuò)誤很可能就會被吃掉,但是使用 promises,我們可以輕易的在 catch() 函數(shù)中處理它了。

一定要注意我們在then 函數(shù)內(nèi)部的時(shí)候

我們可以做什么呢?有三種事情:

return 另一個(gè) promise
return 一個(gè)同步的值 (或者 undefined)
throw 一個(gè)同步異常

參考資料

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

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

相關(guān)文章

  • ES6-7

    摘要:的翻譯文檔由的維護(hù)很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會promise...... 本書的目的是以目前還在制定中的ECMASc...

    mudiyouyou 評論0 收藏0
  • [譯] 深入理解 Promise 五部曲:1. 異步問題

    摘要:當(dāng)引擎開始執(zhí)行一個(gè)函數(shù)比如回調(diào)函數(shù)時(shí),它就會把這個(gè)函數(shù)執(zhí)行完,也就是說只有執(zhí)行完這段代碼才會繼續(xù)執(zhí)行后面的代碼。當(dāng)條件允許時(shí),回調(diào)函數(shù)就會被運(yùn)行。現(xiàn)在,返回去執(zhí)行注冊的那個(gè)回調(diào)函數(shù)。 原文地址:http://blog.getify.com/promis... 在微博上看到有人分享LabJS作者寫的關(guān)于Promise的博客,看了下覺得寫得很好,分五個(gè)部分講解了Promise的來龍去脈。從...

    CHENGKANG 評論0 收藏0
  • 深入理解js引擎的執(zhí)行機(jī)制

    摘要:深入理解引擎的執(zhí)行機(jī)制最近在反省,很多知識都是只會用,不理解底層的知識。在閱讀之前,請先記住兩點(diǎn)是單線程語言的是的執(zhí)行機(jī)制。所以,是存在異步執(zhí)行的,比如單線程是怎么實(shí)現(xiàn)異步的場景描述通過事件循環(huán),所以說,理解了機(jī)制,也就理解了的執(zhí)行機(jī)制啦。 深入理解js引擎的執(zhí)行機(jī)制 最近在反省,很多知識都是只會用,不理解底層的知識。所以在開發(fā)過程中遇到一些奇怪的比較難解決的bug,在思考的時(shí)候就會收...

    feng409 評論0 收藏0
  • JavaScript 異步

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。寫一個(gè)符合規(guī)范并可配合使用的寫一個(gè)符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個(gè)需求:在系統(tǒng)初始化時(shí)通過http獲取一個(gè)第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個(gè)接口,可通過...

    tuniutech 評論0 收藏0
  • 深入理解ES6筆記(十一)Promise與異步編程

    摘要:回調(diào)函數(shù)模式類似于事件模型,因?yàn)楫惒酱a也會在后面的一個(gè)時(shí)間點(diǎn)才執(zhí)行如果回調(diào)過多,會陷入回調(diào)地獄基礎(chǔ)可以當(dāng)做是一個(gè)占位符,表示異步操作的執(zhí)行結(jié)果。函數(shù)可以返回一個(gè),而不必訂閱一個(gè)事件或者向函數(shù)傳遞一個(gè)回調(diào)函數(shù)。 主要知識點(diǎn):Promise生命周期、Promise基本操作、Promise鏈、響應(yīng)多個(gè)Promise以及集成PromiseshowImg(https://segmentfaul...

    RayKr 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<