成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

promise 基礎(chǔ)版(雛形)

羅志環(huán) / 2613人閱讀

摘要:以下方式寫提示未定義涉及閉包作用域鏈的問題改進(jìn)方式調(diào)用實例化回調(diào)函數(shù)執(zhí)行成功,并執(zhí)行函數(shù),此時在回調(diào)隊列里面添加一一個函數(shù),并將的參數(shù)傳遞出去。否則直接執(zhí)行回調(diào)函數(shù),不會由來觸發(fā)的回調(diào)函數(shù)執(zhí)行。

function Promise(fn){
    //需要一個成功時的回調(diào)
    var self = this
    var callback;
    //一個實例的方法,用來注冊異步事件
    self.then = function(done){
      callback = done;
    }
    // resolve 比 then 先執(zhí)行 此時 callback 不存在
    // 所以 加一個 setTimeout 讓resolve 函數(shù)在回調(diào)隊列的末尾
    // 為啥是0秒? 為啥處于回調(diào)隊列末尾?
    //(權(quán)威指南)如果以0毫秒的超時時間來調(diào)用setTimeout(),那么指定的函數(shù)不會立即執(zhí)
    // 行,相反會把它放到隊列中去,等到前面處于等待狀態(tài)的事件處理程序全部執(zhí)行完成后,
    // 再“立即”調(diào)用它。
    // 以下 方式寫 提示 resolve 未定義 涉及閉包 作用域鏈的問題
    // setTimeout(function () {
    //   function resolve(value){
    //      callback && callback(value);
    //   }
    // }, 0)
    
    // 改進(jìn)方式
    function resolve (value) {
      setTimeout(function () {
        callback && callback(value)
      }, 0)
    }
    fn(resolve);
  }

調(diào)用promise

 // 實例化promise 回調(diào)函數(shù)fn執(zhí)行成功,并執(zhí)行resolve函數(shù),此時在回調(diào)隊列里面添加一
 // 一個callback函數(shù),并將resolve的參數(shù)傳遞出去。
 var promise = new Promise(function (resolve) {
    resolve(["3", "aaa"])
 })
// 調(diào)用then函數(shù),并執(zhí)行then回調(diào),將then函數(shù)的參數(shù)done回調(diào)函數(shù)賦值給callback,
// 在回調(diào)隊列里面(之前setTimeout添加進(jìn)去的回調(diào)隊列)執(zhí)行then的回調(diào)函數(shù)
 promise.then(function (data) {
    console.log("data", data)
 })

但是以上方式寫,我們永遠(yuǎn)都只能執(zhí)行then中一個回調(diào)隊列,這顯然不健壯。我們結(jié)合js設(shè)計模式的發(fā)布--消息訂閱模式,再結(jié)合構(gòu)造函數(shù)return this 知識點,稍微改造下:

function Promise(fn){
    //需要一個成功時的回調(diào)
    var self = this
    self.deferreds = []; // then函數(shù) 回調(diào)隊列 儲存容器
    //一個實例的方法,用來注冊異步事件
    self.then = function(onFulfilled){
      self.deferreds.push(onFulfilled)
      console.log("self.deferreds", self.deferreds) 
      // 調(diào)用兩次then 回調(diào)隊列會逐個push
      return self // 鏈?zhǔn)秸{(diào)用then
    }

    // 改進(jìn)方式
    function resolve (value) {
      setTimeout(function () {
        self.deferreds.forEach(function (deferred) {
           deferred && deferred(value)
        })
      }, 0)
    }
    fn(resolve);
}

調(diào)用then函數(shù):

promise.then(function (data) {
    console.log("data", data)
}).then(function (resp) {
    console.log("resp", resp)
})

眾所周知,構(gòu)造函數(shù)Promise存在三個互斥狀態(tài):pending、fulfilled、rejected。Promise 對象的狀態(tài)改變,只有兩種可能:從 pending 變?yōu)?fulfilled 和從 pending 變?yōu)?rejected。只要這兩種情況發(fā)生,狀態(tài)就凝固了,不會再變了,會一直保持這個結(jié)果。

所以:我們改進(jìn)代碼如下:

//略
// 初始化設(shè)置狀態(tài)
self.status = "pending"
//略
// ...
//略
// resolve的時候 將狀態(tài)置為
self.status = "fulfilled"
//略

調(diào)用執(zhí)行,同樣可以得到我們想要的數(shù)據(jù)。
但是
但是
但是
僅僅加上上面兩行代碼是不行的,仔細(xì)理解加粗的那幾個字,再結(jié)合我們的代碼來看。
當(dāng)我們調(diào)用then函數(shù)的時候,往我們then回調(diào)隊列里面push回調(diào)函數(shù),最終不管狀態(tài)是pending
還是fulfilled,回調(diào)隊列的函數(shù)都是被resolve函數(shù)觸發(fā)的。這樣就違背了這句話:只要這兩種情況發(fā)生,狀態(tài)就凝固了,不會再變了,會一直保持這個結(jié)果。
當(dāng)我們狀態(tài)改變?yōu)閒ulfilled,我們并沒有真正改變狀態(tài),每次再重新執(zhí)行的時候,我們又重新走了一次then添加回調(diào),然后由resolve來觸發(fā)回調(diào)的過程。
所以then函數(shù)改進(jìn)代碼如下:

// 當(dāng)status == "pending"的時候,我們才往then的回調(diào)隊列push回調(diào)函數(shù)。
// 否則 直接執(zhí)行回調(diào)函數(shù),不會由resolve來觸發(fā)then的回調(diào)函數(shù)執(zhí)行。
if(self.status == "pending") {
  self.deferreds.push(onFulfilled)
  return self
}
onFulfilled(value)
return self // 鏈?zhǔn)秸{(diào)用then

所以加入value后,最終代碼如下:
基本就實現(xiàn)了鏈?zhǔn)秸{(diào)用then的一個帶有pending 和 fulfilled 狀態(tài)的Promise
后續(xù)會加上reject(), rejected以及最難理解的串行promise。

function Promise(fn){
    //需要一個成功時的回調(diào)
    var self = this
    self.deferreds = []; // then函數(shù) 回調(diào)隊列 儲存容器
    self.status = "pending"
    self.value = null
    //一個實例的方法,用來注冊異步事件
    self.then = function(onFulfilled){
      if(self.status == "pending") {
        self.deferreds.push(onFulfilled)
        return self
      }
      onFulfilled(self.value)
      return self // 鏈?zhǔn)秸{(diào)用then
    }

    // 改進(jìn)方式
    function resolve (newValue) {
      setTimeout(function () {
        self.value = newValue
        self.status = "fulfilled"
        self.deferreds.forEach(function (deferred) {
           deferred && deferred(self.value)
        })
      }, 0)
    }
    fn(resolve);
 }
附錄參考文獻(xiàn)

美團(tuán)點評

cn博客

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/107055.html

相關(guān)文章

  • 我了解到的JavaScript異步編程

    摘要:接下來我們看下三類異步編程的實現(xiàn)。事件監(jiān)聽事件發(fā)布訂閱事件監(jiān)聽是一種非常常見的異步編程模式,它是一種典型的邏輯分離方式,對代碼解耦很有用處。 一、 一道面試題 前段時間面試,考察比較多的是js異步編程方面的相關(guān)知識點,如今,正好輪到自己分享技術(shù),所以想把js異步編程學(xué)習(xí)下,做個總結(jié)。下面這個demo 概括了大多數(shù)面試過程中遇到的問題: for(var i = 0; i < 3; i++...

    RichardXG 評論0 收藏0
  • 30分鐘,讓你徹底明白Promise原理

    摘要:鏈?zhǔn)绞侵冈诋?dāng)前達(dá)到狀態(tài)后,即開始進(jìn)行下一個后鄰。在中發(fā)現(xiàn)沒有指定異步操作失敗的回調(diào)時,會直接將函數(shù)返回的,后同設(shè)為狀態(tài),如此達(dá)成執(zhí)行后續(xù)失敗回調(diào)的效果。 原文鏈接 前言 前一陣子記錄了promise的一些常規(guī)用法,這篇文章再深入一個層次,來分析分析promise的這種規(guī)則機(jī)制是如何實現(xiàn)的。ps:本文適合已經(jīng)對promise的用法有所了解的人閱讀,如果對其用法還不是太了解,可以移步我的上...

    Profeel 評論0 收藏0
  • Build Your Own Promise

    摘要:意味著代指的操作由于某些原因失敗。第一步構(gòu)造函數(shù)有三種狀態(tài),。這個構(gòu)造函數(shù)我們可以先這樣寫創(chuàng)建一個時,首先進(jìn)行狀態(tài)初始化。所有的都是的,而并不是所有的對象都是。 一、JavaScript異步編程背景 ? 從去年ES2015發(fā)布至今,已經(jīng)過去了一年多,ES2015發(fā)布的新的語言特性中最為流行的也就莫過于Promise了,Promise使得如今JavaScript異步編程如此輕松愜意...

    susheng 評論0 收藏0
  • Promise原理分析一

    摘要:原理分析一對象用于異步計算。它有兩個參數(shù),分別為在成功和失敗情況下的回調(diào)函數(shù)。實現(xiàn)根據(jù)當(dāng)前狀態(tài)對回調(diào)函數(shù)進(jìn)行處理,同時返回一個新的對象,以便鏈?zhǔn)秸{(diào)用。,注冊回調(diào)函數(shù)到當(dāng)前的對象中或,立即執(zhí)行回調(diào)函數(shù)說明方法只處理被拒絕的情況,并返回一個。 Promise原理分析一 Promise對象用于異步計算。一個Promise對象代表著一個還未完成,但預(yù)期將來會完成的操作。 Note: Promi...

    WilsonLiu95 評論0 收藏0
  • 基于vue-cli3.0的項目工程重新構(gòu)建空白,拿來即用

    摘要:寫在前面使用框架開發(fā)時,很多人會選擇官方提供的腳手架,最新的已經(jīng)更新到完全無配置,只需下載就能方便的使用構(gòu)建的項目工程,但基礎(chǔ)的并不能滿足正常的項目開發(fā),在開發(fā)中我們需要根據(jù)自己的習(xí)慣和業(yè)務(wù)功能而添加些基礎(chǔ)功能。 寫在前面 使用vue框架開發(fā)時,很多人會選擇vue官方提供的cli腳手架,最新的cli已經(jīng)更新到3.0完全無配置,只需下載就能方便的使用vuecli構(gòu)建的項目工程,但基礎(chǔ)的c...

    xingpingz 評論0 收藏0

發(fā)表評論

0條評論

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