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

資訊專欄INFORMATION COLUMN

JAVASCRIPT算法(7)

Ilikewhite / 1780人閱讀

摘要:調(diào)用初始的的方法,將匿名函數(shù)和匿名函數(shù)添加到原始的回調(diào)列表。當(dāng)?shù)臓顟B(tài)發(fā)生了改變,相關(guān)的回調(diào)函數(shù)會(huì)被執(zhí)行,上面注冊(cè)的是的和方法作為的回調(diào)函數(shù),那么的函數(shù)會(huì)在的狀態(tài)改變后被執(zhí)行,那么的狀態(tài)就發(fā)生了改變。

Promise實(shí)現(xiàn)代碼分析

全是去嘗試?yán)斫鈩e人是怎么實(shí)現(xiàn)promise的,感覺(jué)下面這兩個(gè)鏈接的Promise實(shí)現(xiàn)比較好。
實(shí)現(xiàn)1 實(shí)現(xiàn)2

實(shí)現(xiàn)2的配圖以及講解更細(xì)致一點(diǎn),如果能跟著作者舉的例子走一遍,應(yīng)該能夠理解為什么可以then().then().then(),以及理解為啥resolve(Promise)的狀態(tài)為啥是由參數(shù)的promise的狀態(tài)來(lái)決定的,也能理解resolve(value)的參數(shù)是如何傳遞給后續(xù)的通過(guò)then注冊(cè)的function的。但是30分鐘有點(diǎn)少,猶猶豫豫,糾結(jié)得看了好久。

相對(duì)而言,實(shí)現(xiàn)1的較為完整,實(shí)現(xiàn)2的某些東西只是提到了,但是沒(méi)提供實(shí)現(xiàn)。比如resolve/reject都只能調(diào)用一次。
實(shí)現(xiàn)1

function doResolve(fn, onFulfilled, onRejected) {
  var done = false;
  try {
    fn(function (value) {
      if (done) return
      done = true
      onFulfilled(value)
    }, function (reason) {
      if (done) return
      done = true
      onRejected(reason)
    })
  } catch (ex) {
    if (done) return
    done = true
    onRejected(ex)
  }
}

var promise = new Promise(fn);
fn是創(chuàng)建promise傳入的參數(shù),它是一個(gè)function,在創(chuàng)建Promise的過(guò)程中需要被調(diào)用。
這個(gè)fn有兩個(gè)參數(shù),都是function,前面一個(gè)是在fn按照得到了正常的結(jié)果之后調(diào)用的,那么then注冊(cè)的onfulfilled的方法就會(huì)在完成之后調(diào)用。另外一個(gè)就是fn遇到了意料之外的結(jié)果,相應(yīng)的就會(huì)調(diào)用then注冊(cè)的onrejected方法。
doResolve的方法就是讓fn只能調(diào)用一次resolve或者一次reject方法,即只能改變promise的狀態(tài)一次。

this.done = function (onFulfilled, onRejected) {
    // ensure we are always asynchronous
    setTimeout(function () {
      handle({
        onFulfilled: onFulfilled,
        onRejected: onRejected
      });
    }, 0);
  }

這個(gè)done方法主要是把注冊(cè)的方法加入到自己這個(gè)Promise的回調(diào)列表里面。同時(shí)為了保證通過(guò)then方法注冊(cè)的function,都要在resolve之后才能調(diào)用,用了setTimeout來(lái)保證這一點(diǎn)(實(shí)現(xiàn)2是這么說(shuō)的,雖然是在不同的地方用setTimeout)。

function handle(handler) {
    if (state === PENDING) {
      handlers.push(handler);
    } else {
      if (state === FULFILLED &&
        typeof handler.onFulfilled === "function") {
        handler.onFulfilled(value);
      }
      if (state === REJECTED &&
        typeof handler.onRejected === "function") {
        handler.onRejected(value);
      }
    }
  }

handle這個(gè)方法,比實(shí)現(xiàn)2的方法要簡(jiǎn)單一點(diǎn),因?yàn)橄嚓P(guān)的邏輯在then方法里面體現(xiàn)了。
這個(gè)其實(shí)就是通過(guò)當(dāng)前的狀態(tài)來(lái)判斷是把回調(diào)加到回調(diào)列表里面還是直接執(zhí)行fulfill或者reject方法。

this.then = function (onFulfilled, onRejected) {
  var self = this;
  return new Promise(function (resolve, reject) {
    return self.done(function (result) {
      if (typeof onFulfilled === "function") {
        try {
          return resolve(onFulfilled(result));
        } catch (ex) {
          return reject(ex);
        }
      } else {
        return resolve(result);
      }
    }, function (error) {
      if (typeof onRejected === "function") {
        try {
          return resolve(onRejected(error));
        } catch (ex) {
          return reject(ex);
        }
      } else {
        return reject(error);
      }
    });
  });
}

then方法很關(guān)鍵,也較難懂。這邊寫的有點(diǎn)多,感覺(jué)實(shí)現(xiàn)2寫的好一點(diǎn),把這些邏輯放在另外一個(gè)位置而不是在構(gòu)建新promise的過(guò)程中。單純從理解上來(lái)講。
首先分析下每個(gè)參數(shù)的意思。
this.then = function (onFulfilled, onRejected)這里面的onFulfilled,onRejected是then方法給當(dāng)前這個(gè)Promise注冊(cè)的兩個(gè)方法。
return new Promise(function (resolve, reject)這里的return new Promise就是為了新建一個(gè)Promise從而可以進(jìn)行鏈?zhǔn)絫hen方法的調(diào)用. then(fn1,fn2).then(fn3,fn4)=>var promise = then(fn1,fn2);
promise.then(fn3,fn4);resolve和reject則是這個(gè)新生成的promise的狀態(tài)設(shè)置方法。

self.done(function (result),function(error));調(diào)用初始的promise的done方法,將匿名函數(shù)function(result)和匿名函數(shù)function(error)添加到原始promise的回調(diào)列表。
然后再來(lái)看看匿名函數(shù)function(result)應(yīng)該怎么執(zhí)行。

function (result) {
      if (typeof onFulfilled === "function") {
        try {
          return resolve(onFulfilled(result));
        } catch (ex) {
          return reject(ex);
        }
      } else {
        return resolve(result);
      }
    }

如果then方法注冊(cè)的是function,那么肯定是要用這個(gè)function去執(zhí)行,onFulfilled(result)就是這個(gè)作用。
resolve是新產(chǎn)生的resolve的狀態(tài)設(shè)定器。執(zhí)行完onFulfilled(result),產(chǎn)生的結(jié)果假如是newresult再交給resolve去執(zhí)行。新的promise的resolve方法就會(huì)將新的promise的狀態(tài)設(shè)置成fulfilled,那么新promise的then方法就可以在注冊(cè)完后續(xù)的方法后接著執(zhí)行。resolve(newresult)就將onFulfilled(result)產(chǎn)生的結(jié)果
傳遞給了后續(xù)的then方法注冊(cè)的function。

function getThen(value) {
  var t = typeof value;
  if (value && (t === "object" || t === "function")) {
    var then = value.then;
    if (typeof then === "function") {
      return then;
    }
  }
  return null;
}

getThen方法是為了查看這個(gè)結(jié)果是不是一個(gè)Promise或者說(shuō)是含有then方法的Object.如果有then方法,就把then方法返回,否則就返回null

  function resolve(result) {
    try {
      var then = getThen(result);
      if (then) {
        doResolve(then.bind(result), resolve, reject)
        return
      }
      fulfill(result);
    } catch (e) {
      reject(e);
    }
  }

resolve這個(gè)方法可以處理參數(shù)是正常數(shù)值或者是Promise。根據(jù)Promise的使用說(shuō)明,A promise resolve(Promise B),那么Promise A的狀態(tài)會(huì)在Promise B的狀態(tài)發(fā)生變化(變成fulfilled或者rejected)才會(huì)變化。首先用getThen來(lái)確定給定的參數(shù)是不是有then函數(shù)的Object,如果不是,那么就是單純的將值賦給Promise A的內(nèi)部變量value,后續(xù)回調(diào)函數(shù)就可以用這個(gè)value作為參數(shù),這也是為什么resolve能把其參數(shù)傳給通過(guò)then注冊(cè)的回調(diào)函數(shù)。那么如果是有then函數(shù)的object呢,首先getThen返回了那個(gè)object的then函數(shù)。
然后then.bind(result)是讓then函數(shù)的調(diào)用在擁有這個(gè)then函數(shù)的object里面執(zhí)行,也就是resolve的參數(shù)result。然后doResolve實(shí)際上也就是執(zhí)行了result這個(gè)promise的then方法。只不過(guò)注冊(cè)的兩個(gè)方法是當(dāng)前這個(gè)
promise的resolve和reject方法。
所以實(shí)際上執(zhí)行的是promiseB.then(resolve,reject);根據(jù)我們前面對(duì)then方法的分析可以知道。當(dāng)promiseB的狀態(tài)發(fā)生了改變,相關(guān)的回調(diào)函數(shù)會(huì)被執(zhí)行,上面注冊(cè)的是Promise A的resolve和reject方法作為promiseB的回調(diào)函數(shù),那么Promise A的resolve/reject函數(shù)會(huì)在promiseB的狀態(tài)改變后被執(zhí)行,那么PromiseA的狀態(tài)就發(fā)生了改變。同時(shí)PromiseB中產(chǎn)生的結(jié)果也會(huì)通過(guò)resolve這個(gè)函數(shù)傳給Promise A.

這個(gè)其實(shí)看實(shí)現(xiàn)2的handle方法以及then如何調(diào)用handle方法會(huì)更容易理解一點(diǎn)。而且作者畫了個(gè)很詳細(xì)的圖。

還忘了一點(diǎn),就是為啥then方法前面有this。后來(lái)我覺(jué)得無(wú)所謂,然后把this去掉了,結(jié)果在調(diào)用的時(shí)候沒(méi)法調(diào)用這個(gè)then函數(shù)。this.then應(yīng)該是接口吧。雖然當(dāng)時(shí)在W3Cschool上學(xué)習(xí)原型構(gòu)造的時(shí)候很認(rèn)真,但是還是忽略了習(xí)以為常的this。直到有的function有this,有的沒(méi)有,才感覺(jué)有點(diǎn)奇怪,我自己寫的時(shí)候怎么判斷要不要加this啊。

大致就是這樣。匿名函數(shù)的調(diào)用,傳入的參數(shù)以及實(shí)際使用的參數(shù),會(huì)引起很多干擾,說(shuō)到底還是不太熟悉javascript的調(diào)用和特色吧。但是應(yīng)該有更好的書寫方式吧。所說(shuō)的東西只是自以為是的理解,實(shí)在很難確信自己是對(duì)的。因?yàn)橛X(jué)得是對(duì)的,所以就會(huì)朝那個(gè)方向去靠,有點(diǎn)像老師解答試卷的標(biāo)準(zhǔn)答案一樣,即使標(biāo)準(zhǔn)答案是錯(cuò)的。網(wǎng)上還是充斥著很多不怎么準(zhǔn)確的東西的,還是按照自己的意愿、想法去測(cè)試下。

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

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

相關(guān)文章

  • 遺傳算法解背包問(wèn)題(javascript實(shí)現(xiàn))

    摘要:遺傳算法物競(jìng)天擇,適者生存,遺傳算法就是借鑒生物體自然選擇和自然遺傳機(jī)制的隨機(jī)搜索算法。隨機(jī)生成的基因適應(yīng)度的最大值隨機(jī)生成,適應(yīng)度函數(shù)計(jì)算種群中所有對(duì)象的適應(yīng)度及總和,并對(duì)超出的基因進(jìn)行懲罰。 此為《算法的樂(lè)趣》讀書筆記,我用javascript(ES6)重新實(shí)現(xiàn)算法。 遺傳算法 物競(jìng)天擇,適者生存,遺傳算法就是借鑒生物體自然選擇和自然遺傳機(jī)制的隨機(jī)搜索算法。算法的關(guān)鍵點(diǎn)有:基因的選...

    longshengwang 評(píng)論0 收藏0
  • 優(yōu)秀程序員都應(yīng)該學(xué)習(xí)的 GitHub 上開(kāi)源的數(shù)據(jù)結(jié)構(gòu)與算法項(xiàng)目

    摘要:強(qiáng)烈推薦上值得前端學(xué)習(xí)的數(shù)據(jù)結(jié)構(gòu)與算法項(xiàng)目,包含圖的演示過(guò)程與視頻講解。該倉(cāng)庫(kù)包含了多種基于的算法與數(shù)據(jù)結(jié)構(gòu),提供進(jìn)一步閱讀的解釋和鏈接。數(shù)據(jù)結(jié)構(gòu)和算法必知必會(huì)的個(gè)代碼實(shí)現(xiàn)。 showImg(https://segmentfault.com/img/bVbvpYZ); 前言 算法為王。想學(xué)好前端,先練好內(nèi)功,內(nèi)功不行,就算招式練的再花哨,終究成不了高手;只有內(nèi)功深厚者,前端之路才會(huì)走得...

    cheukyin 評(píng)論0 收藏0
  • JavaScript 數(shù)據(jù)結(jié)構(gòu)與算法之美 - 十大經(jīng)典排序算法匯總

    摘要:筆者寫的數(shù)據(jù)結(jié)構(gòu)與算法之美系列用的語(yǔ)言是,旨在入門數(shù)據(jù)結(jié)構(gòu)與算法和方便以后復(fù)習(xí)。這應(yīng)該是目前較為簡(jiǎn)單的十大經(jīng)典排序算法的文章講解了吧。比如原本在的前面,而,排序之后,在的后面十大經(jīng)典排序算法冒泡排序思想冒泡排序只會(huì)操作相鄰的兩個(gè)數(shù)據(jù)。 showImg(https://segmentfault.com/img/bVbvHet); 1. 前言 算法為王。想學(xué)好前端,先練好內(nèi)功,內(nèi)功不行,就...

    zsy888 評(píng)論0 收藏0
  • 排序算法回顧(JavaScript

    摘要:回顧選擇排序,插入排序,冒泡排序,快速排序,希爾排序,歸并排序,堆排序以及如何計(jì)算時(shí)間復(fù)雜度學(xué)習(xí)文章同學(xué)的描述數(shù)據(jù)結(jié)構(gòu)等同學(xué)的十大經(jīng)典算法本文代碼也上傳到了排序算法回顧。但希爾排序是非穩(wěn)定排序算法。 回顧選擇排序,插入排序,冒泡排序,快速排序,希爾排序,歸并排序,堆排序以及如何計(jì)算時(shí)間復(fù)雜度學(xué)習(xí)文章:hahda同學(xué)的javascript描述數(shù)據(jù)結(jié)構(gòu)、hustcc等同學(xué)的十大經(jīng)典算法 ...

    jlanglang 評(píng)論0 收藏0
  • JavaScript 數(shù)據(jù)結(jié)構(gòu)與算法之美 - 桶排序、計(jì)數(shù)排序、基數(shù)排序

    摘要:之所以把計(jì)數(shù)排序桶排序基數(shù)排序放在一起比較,是因?yàn)樗鼈兊钠骄鶗r(shí)間復(fù)雜度都為。動(dòng)畫計(jì)數(shù)排序思想找出待排序的數(shù)組中最大和最小的元素。桶排序計(jì)數(shù)排序能派上用場(chǎng)嗎手機(jī)號(hào)碼有位,范圍太大,顯然不適合用這兩種排序算法。 showImg(https://segmentfault.com/img/bVbuF9e?w=900&h=500); 1. 前言 算法為王。 想學(xué)好前端,先練好內(nèi)功,只有內(nèi)功深厚者...

    Awbeci 評(píng)論0 收藏0
  • JavaScript 數(shù)據(jù)結(jié)構(gòu)與算法之美 - 冒泡排序、插入排序、選擇排序

    摘要:之所以把冒泡排序選擇排序插入排序放在一起比較,是因?yàn)樗鼈兊钠骄鶗r(shí)間復(fù)雜度都為。其中,冒泡排序就是原地排序算法。所以冒泡排序是穩(wěn)定的排序算法。選擇排序思路選擇排序算法的實(shí)現(xiàn)思路有點(diǎn)類似插入排序,也分已排序區(qū)間和未排序區(qū)間。 showImg(https://segmentfault.com/img/bVbuvnj?w=900&h=250); 1. 前言 算法為王。 想學(xué)好前端,先練好內(nèi)功,...

    canger 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

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