摘要:對(duì)象用于延遲計(jì)算和異步計(jì)算。一個(gè)對(duì)象代表著一個(gè)還未完成,但預(yù)期將來(lái)會(huì)完成的操作。接收一個(gè)函數(shù)作為參數(shù)接收函數(shù)作為參數(shù)支持鏈?zhǔn)秸{(diào)用是按照順序來(lái)執(zhí)行的,并且由觸發(fā)。下篇繼續(xù)完善,例如數(shù)據(jù)傳遞以及中函數(shù)返回一個(gè)時(shí),如何處理。
Promise 對(duì)象用于延遲(deferred) 計(jì)算和異步(asynchronous ) 計(jì)算。一個(gè)Promise對(duì)象代表著一個(gè)還未完成,但預(yù)期將來(lái)會(huì)完成的操作。
先來(lái)一個(gè)例子 A 熟悉下語(yǔ)法
var p = new Promise(function(resolve, reject){ console.log("1"); // 運(yùn)行后續(xù)的 callback 列表,例如:then,when等。否則,不會(huì)執(zhí)行then里面的函數(shù) resolve("go next"); }); // 只考慮成功 p.then(function(){ console.log(2, arguments); return "next"; }, null).then(function(){ console.log(3, arguments) }, null); // 輸出 1 2 ["go next"] 3 ["next"]
最初的設(shè)想
function Promise(func){ // 接收一個(gè)函數(shù)作為參數(shù) } Promise.prototype = { then: function(callback){ // 接收函數(shù)作為參數(shù) return this; // 支持鏈?zhǔn)秸{(diào)用 } }
觀察例 A,resolve是一個(gè)函數(shù),并且不是用戶(hù)傳的,所有Promise自身應(yīng)該有一個(gè)resolve方法,并且這個(gè)方法要傳遞給Promise構(gòu)造器里面的函數(shù)作為參數(shù)。
function Promise(func){ // 接收一個(gè)函數(shù)作為參數(shù) **func(this.resolve);** } Promise.prototype = { **resolve: function(){ }**, then: function(callback){ // 接收函數(shù)作為參數(shù) return this; // 支持鏈?zhǔn)秸{(diào)用 } }
Promise是按照順序來(lái)執(zhí)行callback的,并且由resolve觸發(fā)。
function Promise(func){ // 接收一個(gè)函數(shù)作為參數(shù) **this.doneList = []; // callback 列表** **func(this.resolve.bind(this)); // 順帶綁定this對(duì)象** } Promise.prototype = { resolve: function(){ **//執(zhí)行回調(diào)列表 while(true){ if( this.doneList.length === 0 ){ break; } this.doneList.shift().apply(this); }** }, then: function(callback){ // 接收函數(shù)作為參數(shù) **this.doneList.push(callback); // 加入到回調(diào)隊(duì)列** return this; // 支持鏈?zhǔn)秸{(diào)用 } }
好,現(xiàn)在寫(xiě)一個(gè)測(cè)試用例
var p =new Promise(function(resolve){ console.log("a"); resolve(); }).then(function(){ console.log("b"); }); // 輸出 "a"
什么鬼?打印下p
console.log(p);
我們發(fā)現(xiàn)原來(lái)doneList里面還有一個(gè)函數(shù)沒(méi)有運(yùn)行,再運(yùn)行下這個(gè)函數(shù)
p.doneList[0].call(this); //結(jié)果 console.log("b"); // 打印 b
打斷點(diǎn)跟蹤,發(fā)現(xiàn)Promise先執(zhí)行resolve方法,然后執(zhí)行then,把函數(shù)push到doneList。但是,再也沒(méi)有執(zhí)行過(guò)doneList里面的函數(shù)了。怎么辦呢?我們可以給Promise加一個(gè)屬性(state)來(lái)描述當(dāng)前狀態(tài),分為【未完成】(pending)和【完成】(done)。如果執(zhí)行then時(shí),狀態(tài)已經(jīng)是完成態(tài),那么切換到未完成態(tài),并執(zhí)行resolve方法。
function Promise(func){ // 接收一個(gè)函數(shù)作為參數(shù) **this.state = "pending"; // 初始化狀態(tài)** this.doneList = []; // callback 列表 func(this.resolve.bind(this)); // 順帶綁定this對(duì)象 } Promise.prototype = { resolve: function(){ //執(zhí)行回調(diào)列表 while(true){ if( this.doneList.length === 0 ){ **this.state = "done"; // 回調(diào)列表為空,改變狀態(tài)** break; } this.doneList.shift().apply(this); } }, then: function(callback){ // 也是接收函數(shù) this.doneList.push(callback); // 加入到回調(diào)隊(duì)列 if( this.state === "done"){ this.state = "pneding"; this.resolve(); } return this; // 支持鏈?zhǔn)秸{(diào)用 } }
用和上面類(lèi)似的例子再次測(cè)試
var p =new Promise(function(resolve){ console.log("a"); resolve(); }).then(function(){ console.log("b"); }).then(function(){ console.log("c"); });
結(jié)果截圖
這下,我們自定義的Promise基礎(chǔ)功能完成了最核心的部分了。也許有人會(huì)疑問(wèn),你這寫(xiě)的什么鬼?下面的代碼更簡(jiǎn)單,也能實(shí)現(xiàn)相同的功能
function Promise(func){ // 接收一個(gè)函數(shù)作為參數(shù) func(this.resolve.bind(this)); // 順帶綁定this對(duì)象 } Promise.prototype = { resolve: function(){ //什么也不干 }, then: function(callback){ // 也是接收函數(shù) callback.call(this); // 直接運(yùn)行 return this; // 支持鏈?zhǔn)秸{(diào)用 } }
測(cè)試用例
var p =new Promise(function(resolve){ console.log("d"); resolve(); }).then(function(){ console.log("e"); }).then(function(){ console.log("f"); });
結(jié)果:
但是,文章最前面說(shuō)過(guò)
Promise 對(duì)象用于延遲(deferred) 計(jì)算和異步(asynchronous ) 計(jì)算
并且會(huì)順序執(zhí)行回調(diào)列表(doneList)。最終代碼及測(cè)試
function Promise(func){ this.state = "pending"; this.doneList = []; func(this.resolve.bind(this)); } Promise.prototype = { resolve: function(){ while(true){ if( this.doneList.length === 0 ){ this.state = "done"; break; } this.doneList.shift().apply(this); } }, then: function(callback){ this.doneList.push(callback); if( this.state === "done"){ this.state = "pending"; this.resolve(); } return this; } } var p = new Promise(function(resolve){ window.setTimeout(function(){ console.log("d"); resolve(); }, 1000); }).then(function(){ console.log("e"); }).then(function(){ console.log("f"); }); console.log("被阻塞了嗎?");
輸出:
先輸出"被阻塞了嗎?",一秒鐘后相繼輸出 d、e、f 。可以看出,不但沒(méi)有阻塞后面的代碼執(zhí)行,而且回調(diào)也是按照順序執(zhí)行的。
結(jié)束。
下篇繼續(xù)完善,例如數(shù)據(jù)傳遞以及then中函數(shù)返回一個(gè)Promise時(shí),如何處理。歡迎大家有疑問(wèn)或者建議,一起來(lái)交流。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/78535.html
摘要:今天我們接著上次的內(nèi)容繼續(xù)扯,如何實(shí)現(xiàn)數(shù)據(jù)傳遞以及當(dāng)回調(diào)函數(shù)返回一個(gè)新的上篇已完成的代碼測(cè)試代碼上面的結(jié)果,就是我們要實(shí)現(xiàn)的。然后,等到下次需要的時(shí)候,再傳給下一個(gè)回調(diào)函數(shù)。先來(lái)修改方法,因?yàn)榛卣{(diào)函數(shù)都是在這里運(yùn)行的。 上一篇文章【實(shí)現(xiàn)簡(jiǎn)易 ES6 Promise 功能 (一)】實(shí)現(xiàn)了基本的異步功能。今天我們接著上次的內(nèi)容繼續(xù)扯,如何實(shí)現(xiàn)【數(shù)據(jù)傳遞】以及當(dāng)【回調(diào)函數(shù)返回一個(gè)新的prom...
前言 作為一個(gè)后端過(guò)來(lái)的同學(xué),剛?cè)腴T(mén)前端的時(shí)候,被js種種「反人類(lèi)」的概念折騰的死去活來(lái)的.其中一個(gè)印象比較深刻的,就是promise,感覺(jué)實(shí)在太難理解了...所有就有了寫(xiě)個(gè)簡(jiǎn)單的promise的想法.希望能幫助到一些跟我一樣,感覺(jué)promise很難理解的新同學(xué). promise的教程網(wǎng)上多如牛毛,其中寫(xiě)的比較通俗易懂的莫過(guò)于阮一峰的es6,反正我是他的書(shū)才懂的.所以今天,我們也不會(huì)來(lái)復(fù)述一遍如何...
摘要:遍歷器原有的表示集合的數(shù)據(jù)結(jié)構(gòu),主要有和,在中又加入了和,這樣就有了四種數(shù)據(jù)集合,還可以組合使用它們,如數(shù)組的成員是或,這樣就需要一種統(tǒng)一的接口機(jī)制,用來(lái)處理所有不同的數(shù)據(jù)結(jié)構(gòu)。 showImg(https://segmentfault.com/img/remote/1460000018998438?w=900&h=431); 閱讀原文 Generators 簡(jiǎn)介 Generato...
摘要:在處理異步回調(diào)函數(shù)的情況有著越來(lái)越值得推崇的方法及類(lèi)庫(kù),下面會(huì)依次介紹處理異步函數(shù)的發(fā)展史,及源碼解讀。而對(duì)象的狀態(tài),是由第一個(gè)的參數(shù)成功回調(diào)函數(shù)或失敗回調(diào)函數(shù)的返回值決定的。 函數(shù)的執(zhí)行分為同步和異步兩種。同步即為 同步連續(xù)執(zhí)行,通俗點(diǎn)講就是做完一件事,再去做另一件事。異步即為 先做一件事,中間可以去做其他事情,稍后再回來(lái)做第一件事情。同時(shí)還要記住兩個(gè)特性:1.異步函數(shù)是沒(méi)有返回值的...
摘要:如果狀態(tài)是等待態(tài)的話,就往回調(diào)函數(shù)中函數(shù),比如如下代碼就會(huì)進(jìn)入等待態(tài)的邏輯以上就是簡(jiǎn)單版實(shí)現(xiàn)實(shí)現(xiàn)一個(gè)符合規(guī)范的接下來(lái)大部分代碼都是根據(jù)規(guī)范去實(shí)現(xiàn)的。 為更好的理解, 推薦閱讀Promise/A+ 規(guī)范 實(shí)現(xiàn)一個(gè)簡(jiǎn)易版 Promise 在完成符合 Promise/A+ 規(guī)范的代碼之前,我們可以先來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)易版 Promise,因?yàn)樵诿嬖囍校绻隳軐?shí)現(xiàn)出一個(gè)簡(jiǎn)易版的 Promise ...
閱讀 2715·2021-11-22 13:52
閱讀 1184·2021-10-14 09:43
閱讀 3640·2019-08-30 15:56
閱讀 2952·2019-08-30 13:22
閱讀 3269·2019-08-30 13:10
閱讀 1563·2019-08-26 13:45
閱讀 1102·2019-08-26 11:47
閱讀 2789·2019-08-23 18:13