摘要:,表示當(dāng)前中的方法的第一個(gè)回調(diào)函數(shù)。在函數(shù)執(zhí)行時(shí),我們會(huì)創(chuàng)建一個(gè)新的,然后將傳入的兩個(gè)回調(diào)函數(shù)用新的的屬性保存下來。首先我們需要先創(chuàng)建一個(gè)新的用于返回,保證后面用戶調(diào)用函數(shù)進(jìn)行后續(xù)邏輯處理時(shí)可以設(shè)置新的和這兩個(gè)回調(diào)函數(shù)。
概述
從上次更新Promise/A+規(guī)范后,已經(jīng)很久沒有更新博客了。之前由于業(yè)務(wù)需要,完成了一個(gè)TypeScript語言的Promise庫。這次我們來和大家一步一步介紹下,我們?nèi)绾螌?shí)現(xiàn)一個(gè)符合Promise/A+規(guī)范的Promise庫。
如果對(duì)Promise/A+規(guī)范還不太了解的同學(xué),建議先看看上一篇博客——前端基礎(chǔ)知識(shí)儲(chǔ)備——Promise/A+規(guī)范。
實(shí)現(xiàn)流程首先,我們來看下,在我實(shí)現(xiàn)的這一個(gè)Promise中,代碼由下面這幾部分組成:
全局異步函數(shù)執(zhí)行器
常量與屬性
類方法
類靜態(tài)方法
通過上面這四個(gè)部分,我們就能夠得到一個(gè)完整的Promise。這四個(gè)部分互相有關(guān)聯(lián),接下來我們一個(gè)一個(gè)模塊來看。
全局異步函數(shù)執(zhí)行器在之前的Promiz的源碼分析的博客中我有提到過,我們?nèi)绾蝸韺?shí)現(xiàn)一個(gè)異步函數(shù)執(zhí)行器。通過JavaScript的執(zhí)行原理我們可以知道,如果要實(shí)現(xiàn)異步執(zhí)行相關(guān)函數(shù)的話,我們可以選擇使用宏任務(wù)和微任務(wù),這一點(diǎn)在Promise/A+的規(guī)范中也有提及。因此,下面我們提供了一個(gè)用宏任務(wù)來實(shí)現(xiàn)異步函數(shù)執(zhí)行器的代碼供大家參考。
let index = 0; if (global.postMessage) { global.addEventListener("message", (e) => { if (e.source === global) { let id = e.data; if (isRunningTask) { nextTick(functionStorage[id]); } else { isRunningTask = true; try { functionStorage[id](); } catch (e) { } isRunningTask = false; } delete functionStorage[id]; functionStorage[id] = void 0; } }); } function nextTick(func) { if (global.setImmediate) { global.setImmediate(func); } else if (global.postMessage) { functionStorage[++index] = func; global.postMessage(index, "*") } else { setTimeout(func); } }
通過上面的代碼我們可以看到,我們一共使用了setImmediate、postMessage、setTimeout這三個(gè)添加宏任務(wù)的方法來進(jìn)行一步函數(shù)執(zhí)行。
常量與屬性說完了如何進(jìn)行異步函數(shù)的執(zhí)行,我們來看下相關(guān)的常量與屬性。在實(shí)現(xiàn)Promise之前,我們需要定義一些常量和類屬性,用于后面存儲(chǔ)數(shù)據(jù)。讓我們一個(gè)一個(gè)來看下。
常量首先,Promise共有5個(gè)狀態(tài),我們需要用常量來進(jìn)行定義,具體如下:
enum State { pending = 0, resolving = 1, rejecting = 2, resolved = 3, rejected = 4 };
這五個(gè)常量分別對(duì)應(yīng)Promise中的5個(gè)狀態(tài),相信大家能夠從名字中理解,我們就不多講了。
屬性在Promise中,我們需要一些屬性來存儲(chǔ)數(shù)據(jù)狀態(tài)和后續(xù)的Promise引用,具體如下:
class Promise { private _value; private _reason; private _next = []; public state: State = 0; public fn; public er; }
我們對(duì)屬性進(jìn)行逐一說明:
_value,表示在resolved狀態(tài)時(shí),用來存儲(chǔ)當(dāng)前的值。
_reason,表示在rejected狀態(tài)時(shí),用來存儲(chǔ)當(dāng)前的原因。
_next,表示當(dāng)前Promise后面跟著then函數(shù)的引用。
fn,表示當(dāng)前Promise中的then方法的第一個(gè)回調(diào)函數(shù)。
er,表示當(dāng)前Promise中的then方法的的第二個(gè)回調(diào)函數(shù)(即catch的第一個(gè)參數(shù),下面看catch實(shí)現(xiàn)方法就能理解)。
類方法看完了常量與類的屬性,我們來看下類的靜態(tài)方法。
Constructor首先,如果我們要實(shí)現(xiàn)一個(gè)Promise,我們需要一個(gè)構(gòu)造函數(shù)來初始化最初的Promise。具體代碼如下:
class Promise { constructor(resolver?) { if (typeof resolver !== "function" && resolver !== undefined) { throw TypeError() } if (typeof this !== "object") { throw TypeError() } try { if (typeof resolver === "function") { resolver(this.resolve.bind(this), this.reject.bind(this)); } } catch (e) { this.reject(e); } } }
從Promise/A+的規(guī)范來看,我們可以知道,如果resolver存在并且不是一個(gè)function的話,那么我們就應(yīng)該拋出一個(gè)錯(cuò)誤;否則,我們應(yīng)該將resolve和reject方法傳給resolver作為參數(shù)。
resolve && reject那么,resolve和reject方法又是做什么的呢?這兩個(gè)方法主要是用來讓當(dāng)前的這個(gè)Promise轉(zhuǎn)換狀態(tài)的,即從pending狀態(tài)轉(zhuǎn)換為resolving或者rejecting狀態(tài)。下面讓我們來具體看下代碼:
class Promise { resolve(value) { if (this.state === State.pending) { this._value = value; this.state = State.resolving; nextTick(this._handleNextTick.bind(this)); } return this; } reject(reason) { if (this.state === State.pending) { this._reason = reason; this.state = State.rejecting; this._value = void 0; nextTick(this._handleNextTick.bind(this)); } return this; } }
從上面的代碼中我們可以看到,當(dāng)resolve或者reject方法被觸發(fā)時(shí),我們都改變了當(dāng)前這個(gè)Proimse的狀態(tài),并且異步調(diào)用執(zhí)行了_handleNextTick方法。狀態(tài)的改變標(biāo)志著當(dāng)前的Promise已經(jīng)從pending狀態(tài)改變成了resolving或者rejecting狀態(tài),而相應(yīng)_value和_reson也表示上一個(gè)Promise傳遞給下一個(gè)Promise的數(shù)據(jù)。
那么,這個(gè)_handleNextTick方法又是做什么的呢?其實(shí),這個(gè)方法的作用很簡(jiǎn)單,就是用來處理當(dāng)前這個(gè)Promise后面跟著的then函數(shù)傳遞進(jìn)來的回調(diào)函數(shù)fn和er。
then && catch在了解_handleNextTick之前,我們們先看下then函數(shù)和catch函數(shù)的實(shí)現(xiàn)。
class Promise { public then(fn, er?) { let promise = new Promise(); promise.fn = fn; promise.er = er; if (this.state === State.resolved) { promise.resolve(this._value); } else if (this.state === State.rejected) { promise.reject(this._reason); } else { this._next.push(promise); } return promise; } public catch(er) { return this.then(null, er); } }
因?yàn)?b>catch函數(shù)調(diào)用就是一個(gè)then函數(shù)的別名,我們下面就只討論then函數(shù)。
在then函數(shù)執(zhí)行時(shí),我們會(huì)創(chuàng)建一個(gè)新的Promise,然后將傳入的兩個(gè)回調(diào)函數(shù)用新的Promise的屬性保存下來。然后,先判斷當(dāng)前的Promise的狀態(tài),如果已經(jīng)是resolved或者rejected狀態(tài)時(shí),我們立即調(diào)用新的Promise中resolve或者reject方法,讓下將當(dāng)前Promise的_value或者_reason傳遞給下一個(gè)Promise,并且觸發(fā)下一個(gè)Promise的狀態(tài)改變。如果當(dāng)前Promise的狀態(tài)仍然為pending時(shí),那么就將這個(gè)新生成的Promise保存下來,等當(dāng)前這個(gè)Promise的狀態(tài)改變后,再觸發(fā)新的Promise變化。最后,我們返回了這個(gè)Promise的實(shí)例。
handleNextTick看完了then函數(shù),我們就可以來看下我們提到過的handleNextTick函數(shù)。
class Promise { private _handleNextTick() { try { if (this.state === State.resolving && typeof this.fn === "function") { this._value = this.fn.call(getThis(), this._value); } else if (this.state === State.rejecting && typeof this.er === "function") { this._value = this.er.call(getThis(), this._reason); this.state = 1; } } catch (e) { this.state = State.rejecting; this._reason = e; this._value = void 0; this._finishThisTypeScriptPromise(); } // if promise === x, use TypeError to reject promise // 如果promise和x指向同一個(gè)對(duì)象,那么用TypeError作為原因拒絕promise if (this._value === this) { this.state = State.rejecting; this._reason = new TypeError(); this._value = void 0; } this._finishThisTypeScriptPromise(); } }
我們先來看一個(gè)簡(jiǎn)單版的_handleNextTick函數(shù),這樣能夠幫助我們快速理解Promise主流程。
異步觸發(fā)了_handleNextTick函數(shù)后,我們會(huì)判斷當(dāng)前用戶處于的狀態(tài),如果當(dāng)前Promise是resolving狀態(tài),我們就會(huì)調(diào)用fn函數(shù),即我們?cè)?b>then函數(shù)調(diào)用時(shí)給新的Promise設(shè)置的那個(gè)fn函數(shù);而如過當(dāng)前Promise是rejecting狀態(tài),我們就會(huì)調(diào)用er函數(shù)。
上面提到的getThis方法是用來獲取特定的this值,具體的規(guī)范要求我們將在稍后再進(jìn)行介紹。
通過執(zhí)行這兩個(gè)同步的fn或er函數(shù),我們能夠得到當(dāng)前Promise執(zhí)行完傳入回調(diào)后的值。在這里需要說明的是:我們?cè)趫?zhí)行fn或者er函數(shù)之前,我們?cè)?b>_value和_reason中存放的值,是上一個(gè)Promise傳遞下來的值。只有當(dāng)執(zhí)行完了fn或者er函數(shù)后,_value和_reason中存放的值才是我們需要傳遞給下一個(gè)Promise的值。
大家到這里可能會(huì)奇怪,我們的this指向沒有發(fā)生變化,但是為什么我們的this指向的是那個(gè)新的Promise,而不是原來的那個(gè)Promise呢?
我們可以從另外一個(gè)角度來看待這個(gè)問題:我們當(dāng)前的這個(gè)Promise是不是由上一個(gè)Promise所產(chǎn)生的呢?如果是這種情況的話,我們就可以理解,在上一個(gè)Promise產(chǎn)生當(dāng)前Promise的時(shí)候,就設(shè)置了fn和er兩個(gè)函數(shù)。
大家可能又會(huì)問,那么我們第一個(gè)Promise的fn和er這兩個(gè)參數(shù)是怎么來的呢?
那么我們就需要仔細(xì)看下上面這個(gè)邏輯了。下面我們只討論第一個(gè)Promise處于pending的情況,其余的情況與這種情形基本相同。第一個(gè)Promise因?yàn)闆]有上一個(gè)Promise去設(shè)置fn和er兩個(gè)參數(shù),因此這兩個(gè)參數(shù)的值就是undefined。所以在上面的邏輯中,我們已經(jīng)排除了這種情況,直接進(jìn)入了_finishThisTypeScriptPromise函數(shù)中。
我們?cè)谶@里需要特別說明下的是,有些人會(huì)認(rèn)為我們?cè)谡{(diào)用then函數(shù)傳入的兩個(gè)回調(diào)函數(shù)fn和er時(shí),當(dāng)前Promise就結(jié)束了,其實(shí)并不是這樣,我們是得到了fn或者er兩個(gè)函數(shù)的返回值,再將值傳遞給下一個(gè)Promise時(shí),上一個(gè)Promise才會(huì)結(jié)束。關(guān)于這個(gè)邏輯我們可以看下_finishThisTypeScriptPromise函數(shù)。
finishThisTypeScriptPromise_finishThisTypeScriptPromise函數(shù)的代碼如下:
class Promise { private _finishThisTypeScriptPromise() { if (this.state === State.resolving) { this.state = State.resolved; this._next.map((nextTypeScriptPromise) => { nextTypeScriptPromise.resolve(this._value); }); } else { this.state = State.rejected; this._next.map((nextTypeScriptPromise) => { nextTypeScriptPromise.reject(this._reason); }); } } }
從_finishThisTypeScriptPromise函數(shù)中我們可以看到,我們?cè)诘玫搅诵枰獋鬟f給下一個(gè)Promise的_value或者_reason后,利用map方法逐個(gè)調(diào)用我們保存的新生成的Promise實(shí)例,調(diào)用它的resolve方法,因此我們又觸發(fā)了這個(gè)Promise的狀態(tài)從pending轉(zhuǎn)變?yōu)?b>resolving或者rejecting。
到這里我們就已經(jīng)完全了解了一個(gè)Promise從最開始的創(chuàng)建,到最后結(jié)束的整個(gè)生命周期。下面我們來看下在Promise/A+規(guī)范中提到的一些分支邏輯的處理情況。
上一個(gè)Promise傳遞的value是Thenable實(shí)例首先,讓我們來了解下什么是Thenable實(shí)例。Thenable實(shí)例指的是屬性中有then函數(shù)的對(duì)象。Promise就是的一種特殊的Thenable對(duì)象。
下面,為了方便講解,我們將用Promise來代替Thenable進(jìn)行講解,其他的Thenable類大家可以參考類似思路進(jìn)行分析。
如果我們?cè)趥鬟f給我們的_value中是一個(gè)Promise實(shí)例,那么我們必須在等待傳入的Promise狀態(tài)轉(zhuǎn)換到resolved之后,當(dāng)前的Promise才能夠繼續(xù)往下執(zhí)行,即我們從傳入的Promise中得到了一個(gè)非Thenable返回值時(shí),我們才能用這個(gè)值來調(diào)用屬性中的fn或者er方法。
那么,我們要怎么樣才能獲取到傳入的這個(gè)Promise的返回值呢?在Promise中其實(shí)用到了一個(gè)非常巧妙的方法:因?yàn)閭魅氲腜romise中有一個(gè)then函數(shù)(Thenable定義),因此我們就調(diào)用then函數(shù),在第一個(gè)回調(diào)函數(shù)fn中傳入獲取_value,觸發(fā)當(dāng)前的Promise繼續(xù)執(zhí)行。如果是觸發(fā)了第二個(gè)回調(diào)函數(shù)er,那么就用在er中得到的_reason來拒絕掉當(dāng)前的Promise。具體判斷邏輯如下:
class Promise { private _handleNextTick() { let ref; let count = 0; try { // 判斷傳入的this._value是否為一個(gè)thanable // check if this._value a thenable ref = this._value && this._value.then; } catch (e) { this.state = State.rejecting; this._reason = e; this._value = void 0; return this._handleNextTick(); } if (this.state !== State.rejecting && (typeof this._value === "object" || typeof this._value === "function") && typeof ref === "function") { // add a then function to get the status of the promise // 在原有TypeScriptPromise后增加一個(gè)then函數(shù)用來判斷原有promise的狀態(tài) try { ref.call(this._value, (value) => { if (count++) { return; } this._value = value; this.state = State.resolving; this._handleNextTick(); }, (reason) => { if (count++) { return; } this._reason = reason; this.state = State.rejecting; this._value = void 0; this._handleNextTick(); }); } catch (e) { this.state = State.rejecting; this._reason = e; this._value = void 0; this._handleNextTick(); } } else { try { if (this.state === State.resolving && typeof this.fn === "function") { this._value = this.fn.call(getThis(), this._value); } else if (this.state === State.rejecting && typeof this.er === "function") { this._value = this.er.call(getThis(), this._reason); this.state = 1; } } catch (e) { this.state = State.rejecting; this._reason = e; this._value = void 0; this._finishThisTypeScriptPromise(); } this._finishThisTypeScriptPromise(); } } }promise === value
在Promise/A+規(guī)范中,如果返回的_value值等于用戶自身時(shí),需要用TypeError錯(cuò)誤拒絕掉當(dāng)前的Promise。因此我們需要在_handleNextTick中加入以下判斷代碼:
class Promise { private _handleNextTick() { let ref; let count = 0; try { // 判斷傳入的this._value是否為一個(gè)thanable // check if this._value a thenable ref = this._value && this._value.then; } catch (e) { this.state = State.rejecting; this._reason = e; this._value = void 0; return this._handleNextTick(); } if (this.state !== State.rejecting && (typeof this._value === "object" || typeof this._value === "function") && typeof ref === "function") { // add a then function to get the status of the promise // 在原有TypeScriptPromise后增加一個(gè)then函數(shù)用來判斷原有promise的狀態(tài) ... } else { try { if (this.state === State.resolving && typeof this.fn === "function") { this._value = this.fn.call(getThis(), this._value); } else if (this.state === State.rejecting && typeof this.er === "function") { this._value = this.er.call(getThis(), this._reason); this.state = 1; } } catch (e) { this.state = State.rejecting; this._reason = e; this._value = void 0; this._finishThisTypeScriptPromise(); } // if promise === x, use TypeError to reject promise // 如果promise和x指向同一個(gè)對(duì)象,那么用TypeError作為原因拒絕promise if (this._value === this) { this.state = State.rejecting; this._reason = new TypeError(); this._value = void 0; } this._finishThisTypeScriptPromise(); } } }getThis
在Promise/A+規(guī)范中規(guī)定:我們?cè)谡{(diào)用fn和er兩個(gè)回調(diào)函數(shù)時(shí),this的指向有限制。在嚴(yán)格模式下,this的值應(yīng)該為undefined;在寬松模式下時(shí),this的值應(yīng)該為global。
因此,我們還需要提供一個(gè)getThis函數(shù)用于處理上述情況。具體代碼如下:
class Promise { ... } function getThis() { return this; }類靜態(tài)方法
我們通過上面說到的類方法和一些特定分支的邏輯處理,我們就已經(jīng)實(shí)現(xiàn)了一個(gè)符合基本功能的Promise類。那么,下面我們來看下ES6中提供的一些標(biāo)準(zhǔn)API我們?nèi)绾蝸磉M(jìn)行實(shí)現(xiàn)。具體API如下:
resolve
reject
all
race
下面我們就一個(gè)一個(gè)方法來看下。
resolve && reject首先我們來看下最簡(jiǎn)單的resolve和reject方法。
class Promise { public static resolve(value?) { if (TypeScriptPromise._d !== 1) { throw TypeError(); } if (value instanceof TypeScriptPromise) { return value; } return new TypeScriptPromise((resolve) => { resolve(value); }); } public static reject(value?) { if (TypeScriptPromise._d !== 1) { throw TypeError(); } return new TypeScriptPromise((resolve, reject) => { reject(value); }); } }
通過上面代碼我們可以看到,resolve和reject方法基本上就是直接使用了內(nèi)部的constructor方法進(jìn)行Promise構(gòu)建。
allclass Promise { public static all(arr) { if (TypeScriptPromise._d !== 1) { throw TypeError(); } if (!(arr instanceof Array)) { return TypeScriptPromise.reject(new TypeError()); } let promise = new TypeScriptPromise(); function done() { // 統(tǒng)計(jì)還有多少未完成的TypeScriptPromise // count the unresolved promise let unresolvedNumber = arr.filter((element) => { return element && element.then; }).length; if (!unresolvedNumber) { promise.resolve(arr); } arr.map((element, index) => { if (element && element.then) { element.then((value) => { arr[index] = value; done(); return value; }); } }); } done(); return promise; } }
下面我們根據(jù)上面的代碼來簡(jiǎn)單說下all函數(shù)的基本思路。
首先我們需要先創(chuàng)建一個(gè)新的Promise用于返回,保證后面用戶調(diào)用then函數(shù)進(jìn)行后續(xù)邏輯處理時(shí)可以設(shè)置新Promise的fn和er這兩個(gè)回調(diào)函數(shù)。
然后,我們?cè)趺传@取上面Promise數(shù)組中每一個(gè)Promise的值呢?方法很簡(jiǎn)單,我們?cè)谇懊婢鸵呀?jīng)介紹過:我們調(diào)用了每一個(gè)Promise的then函數(shù)用來獲取當(dāng)前這個(gè)Promise的值。并且,在每個(gè)Promise完成時(shí),我們都檢查下是否所有的Promise都已經(jīng)完成,如果已經(jīng)完成,則觸發(fā)新Promise的狀態(tài)從pending轉(zhuǎn)換為resolving或者rejecting。
raceclass Promise { public static race(arr) { if (TypeScriptPromise._d !== 1) { throw TypeError(); } if (!(arr instanceof Array)) { return TypeScriptPromise.reject(new TypeError()); } let promise = new TypeScriptPromise(); function done(value?) { if (value) { promise.resolve(value); } let unresolvedNumber = arr.filter((element) => { return element && element.then; }).length; if (!unresolvedNumber) { promise.resolve(arr); } arr.map((element, index) => { if (element && element.then) { element.then((value) => { arr[index] = value; done(value); return value; }); } }); } done(); return promise; } }
race的思路與all基本一致。只是我們?cè)谔幚砗瘮?shù)上不同。當(dāng)我們只要檢測(cè)到數(shù)組中的Promise有一個(gè)已經(jīng)轉(zhuǎn)換到了resolve或者rejected狀態(tài)(通過沒有then函數(shù)來進(jìn)行判斷)時(shí),就會(huì)立即出發(fā)新創(chuàng)建的Promise示例的狀態(tài)從pending轉(zhuǎn)換為resolving或者rejecting。
總結(jié)我們對(duì)Promise的異步函數(shù)執(zhí)行器、常量與屬性、類方法、類靜態(tài)方法進(jìn)行了逐一介紹,讓大家對(duì)整個(gè)Promise的構(gòu)造和聲明周期有了一個(gè)深度的理解和認(rèn)知。在整個(gè)開發(fā)中需要注意到的一些關(guān)鍵點(diǎn)和細(xì)節(jié),我在上面也一一說明了。大家只需要按照這個(gè)思路,對(duì)照Promise/A+規(guī)范就能夠完成一個(gè)符合規(guī)范的Promise庫。
最后,給大家提供一個(gè)Promise/A+測(cè)試工具,大家實(shí)現(xiàn)了自己的Promise后,可以使用這個(gè)工具來測(cè)試是否完全符合整個(gè)Promise/A+規(guī)范。當(dāng)然,大家如果想使用我的現(xiàn)成代碼,也歡迎大家使用我的代碼Github/typescript-proimse。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/100612.html
摘要:前端進(jìn)階進(jìn)階構(gòu)建項(xiàng)目一配置最佳實(shí)踐狀態(tài)管理之痛點(diǎn)分析與改良開發(fā)中所謂狀態(tài)淺析從時(shí)間旅行的烏托邦,看狀態(tài)管理的設(shè)計(jì)誤區(qū)使用更好地處理數(shù)據(jù)愛彼迎房源詳情頁中的性能優(yōu)化從零開始,在中構(gòu)建時(shí)間旅行式調(diào)試用輕松管理復(fù)雜狀態(tài)如何把業(yè)務(wù)邏輯這個(gè)故事講好和 前端進(jìn)階 webpack webpack進(jìn)階構(gòu)建項(xiàng)目(一) Webpack 4 配置最佳實(shí)踐 react Redux狀態(tài)管理之痛點(diǎn)、分析與...
摘要:使用它可以讓頁面請(qǐng)求少量的數(shù)據(jù),而不用刷新整個(gè)頁面?;谑裁创鹚诘氖?。的庫答基于上面的原因,各種庫引用而生,然而最有名的就是的中的。它的一個(gè)優(yōu)勢(shì)異步操作,但的異步操作是基于事件的異步模型,沒有那么友好。 歡迎訪問我的個(gè)人博客:http://www.xiaolongwu.cn 基本知識(shí) 1. Ajax是什么? 答:Ajax是一種可以在瀏覽器和服務(wù)器之間使用異步數(shù)據(jù)傳輸(HTTP請(qǐng)求)...
摘要:為了降低異步編程的復(fù)雜性,所以。難理解請(qǐng)參考的誤區(qū)以及實(shí)踐異步編程的模式異步編程的種方法 異步編程 javascript異步編程, web2.0時(shí)代比較熱門的編程方式,我們平時(shí)碼的時(shí)候也或多或少用到,最典型的就是異步ajax,發(fā)送異步請(qǐng)求,綁定回調(diào)函數(shù),請(qǐng)求響應(yīng)之后調(diào)用指定的回調(diào)函數(shù),沒有阻塞其他代碼的執(zhí)行。還有像setTimeout方法同樣也是異步執(zhí)行回調(diào)的方法。 如果對(duì)異步編程...
摘要:在對(duì)象的構(gòu)造函數(shù)中,將一個(gè)函數(shù)作為第一個(gè)參數(shù)。二對(duì)象中的方法,可以接收構(gòu)造函數(shù)中處理的狀態(tài)變化,并分別對(duì)應(yīng)執(zhí)行。 showImg(https://segmentfault.com/img/remote/1460000008932857); Promise的重要性我認(rèn)為我沒有必要多講,概括起來說就是必須得掌握,而且還要掌握透徹。這篇文章的開頭,主要跟大家分析一下,為什么會(huì)有Promise...
摘要:的翻譯文檔由的維護(hù)很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書的目的是以目前還在制定中的ECMASc...
閱讀 2270·2021-11-15 11:38
閱讀 1218·2021-09-06 15:02
閱讀 3476·2021-08-27 13:12
閱讀 1463·2019-08-30 14:20
閱讀 2461·2019-08-29 15:08
閱讀 711·2019-08-29 14:08
閱讀 1777·2019-08-29 13:43
閱讀 1573·2019-08-26 12:11