欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

這一次,徹底弄懂Promise-創(chuàng)新互聯(lián)

Promise 必須為以下三種狀態(tài)之一:等待態(tài)(Pending)、執(zhí)行態(tài)(Fulfilled)和拒絕態(tài)(Rejected)。一旦Promise 被 resolve 或 reject,不能再遷移至其他任何狀態(tài)(即狀態(tài) immutable)。

創(chuàng)新互聯(lián)建站專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)、松滋網(wǎng)絡(luò)推廣、小程序定制開發(fā)、松滋網(wǎng)絡(luò)營銷、松滋企業(yè)策劃、松滋品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們大的嘉獎;創(chuàng)新互聯(lián)建站為所有大學(xué)生創(chuàng)業(yè)者提供松滋建站搭建服務(wù),24小時服務(wù)熱線:18980820575,官方網(wǎng)址:www.chinadenli.net

基本過程:

  1. 初始化 Promise 狀態(tài)(pending)

  2. 執(zhí)行 then(..) 注冊回調(diào)處理數(shù)組(then 方法可被同一個 promise 調(diào)用多次)

  3. 立即執(zhí)行 Promise 中傳入的 fn 函數(shù),將Promise 內(nèi)部 resolve、reject 函數(shù)作為參數(shù)傳遞給 fn ,按事件機制時機處理

  4. Promise里的關(guān)鍵是要保證,then方法傳入的參數(shù) onFulfilled 和 onRejected,必須在then方法被調(diào)用的那一輪事件循環(huán)之后的新執(zhí)行棧中執(zhí)行。

真正的鏈?zhǔn)絇romise是指在當(dāng)前promise達(dá)到fulfilled狀態(tài)后,即開始進行下一個promise.

鏈?zhǔn)秸{(diào)用

先從 Promise 執(zhí)行結(jié)果看一下,有如下一段代碼:

?new?Promise((resolve,?reject)?=>?{
?setTimeout(()?=>?{
?resolve({?test:?1?})
?resolve({?test:?2?})
?reject({?test:?2?})
?},?1000)
?}).then((data)?=>?{
?console.log('result1',?data)
?},(data1)=>{
?console.log('result2',data1)
?}).then((data)?=>?{
?console.log('result3',?data)
?})
?//result1?{?test:?1?}
?//result3?undefined
復(fù)制代碼

顯然這里輸出了不同的 data。由此可以看出幾點:

  1. 可進行鏈?zhǔn)秸{(diào)用,且每次 then 返回了新的 Promise(2次打印結(jié)果不一致,如果是同一個實例,打印結(jié)果應(yīng)該一致。

  2. 只輸出第一次 resolve 的內(nèi)容,reject 的內(nèi)容沒有輸出,即 Promise 是有狀態(tài)且狀態(tài)只可以由pending -> fulfilled或 pending-> rejected,是不可逆的。

  3. then 中返回了新的 Promise,但是then中注冊的回調(diào)仍然是屬于上一個 Promise 的。

基于以上幾點,我們先寫個基于 PromiseA+ 規(guī)范的只含 resolve 方法的 Promise 模型:

?function?Promise(fn){?
?let?state?=?'pending';
?let?value?=?null;
?const?callbacks?=?[];
?this.then?=?function?(onFulfilled){
?return?new?Promise((resolve,?reject)=>{
?handle({?//橋梁,將新?Promise?的?resolve?方法,放到前一個?promise?的回調(diào)對象中
?onFulfilled,?
?resolve
?})
?})
?}
?function?handle(callback){
?if(state?===?'pending'){
?callbacks.push(callback)
?return;
?}
?
?if(state?===?'fulfilled'){
?if(!callback.onFulfilled){
?callback.resolve(value)
?return;
?}
?const?ret?=?callback.onFulfilled(value)?//處理回調(diào)
?callback.resolve(ret)?//處理下一個?promise?的resolve
?}
?}
?function?resolve(newValue){
?const?fn?=?()=>{
?if(state?!==?'pending')return
?state?=?'fulfilled';
?value?=?newValue
?handelCb()
?}
?
?setTimeout(fn,0)?//基于?PromiseA+?規(guī)范
?}
?
?function?handelCb(){
?while(callbacks.length)?{
?const?fulfiledFn?=?callbacks.shift();
?handle(fulfiledFn);
?};
?}
?
?fn(resolve)
?}
復(fù)制代碼

這個模型簡單易懂,這里最關(guān)鍵的點就是在 then 中新創(chuàng)建的 Promise,它的狀態(tài)變?yōu)?fulfilled 的節(jié)點是在上一個 Promise的回調(diào)執(zhí)行完畢的時候。也就是說當(dāng)一個 Promise 的狀態(tài)被 fulfilled 之后,會執(zhí)行其回調(diào)函數(shù),而回調(diào)函數(shù)返回的結(jié)果會被當(dāng)作 value,返回給下一個 Promise(也就是then 中產(chǎn)生的 Promise),同時下一個 Promise的狀態(tài)也會被改變(執(zhí)行 resolve 或 reject),然后再去執(zhí)行其回調(diào),以此類推下去...鏈?zhǔn)秸{(diào)用的效應(yīng)就出來了。

但是如果僅僅是例子中的情況,我們可以這樣寫:

?new?Promise((resolve,?reject)?=>?{
?setTimeout(()?=>?{
?resolve({?test:?1?})
?},?1000)
?}).then((data)?=>?{
?console.log('result1',?data)
?//dosomething
?console.log('result3')
?})
?//result1?{?test:?1?}
?//result3
復(fù)制代碼

實際上,我們常用的鏈?zhǔn)秸{(diào)用,是用在異步回調(diào)中,以解決"回調(diào)地獄"的問題。如下例子:

new?Promise((resolve,?reject)?=>?{
?setTimeout(()?=>?{
?resolve({?test:?1?})
?},?1000)
}).then((data)?=>?{
?console.log('result1',?data)
?//dosomething
?return?test()
}).then((data)?=>?{
?console.log('result2',?data)
})
function?test(id)?{
?return?new?Promise(((resolve)?=>?{
?setTimeout(()?=>?{
?resolve({?test:?2?})
?},?5000)
?}))
}
//基于第一個?Promise?模型,執(zhí)行后的輸出
//result1?{?test:?1?}
//result2?Promise?{then:??}
復(fù)制代碼

用上面的 Promise 模型,得到的結(jié)果顯然不是我們想要的。認(rèn)真看上面的模型,執(zhí)行 callback.resolve 時,傳入的參數(shù)是 callback.onFulfilled 執(zhí)行完成的返回,顯然這個測試?yán)臃祷氐木褪且粋€ Promise,而我們的 Promise 模型中的 resolve 方法并沒有特殊處理。那么我們將 resolve 改一下:

?function?Promise(fn){?
?...
?function?resolve(newValue){
?const?fn?=?()=>{
?if(state?!==?'pending')return
?if(newValue?&&?(typeof?newValue?===?'object'?||?typeof?newValue?===?'function')){
?const?{then}?=?newValue
?if(typeof?then?===?'function'){
?//?newValue?為新產(chǎn)生的?Promise,此時resolve為上個?promise?的resolve
?//相當(dāng)于調(diào)用了新產(chǎn)生?Promise?的then方法,注入了上個?promise?的resolve?為其回調(diào)
?then.call(newValue,resolve)
?return
?}
?}
?state?=?'fulfilled';
?value?=?newValue
?handelCb()
?}
?
?setTimeout(fn,0)
?}
?...
?}
復(fù)制代碼

用這個模型,再測試我們的例子,就得到了正確的結(jié)果:

?new?Promise((resolve,?reject)?=>?{
?setTimeout(()?=>?{
?resolve({?test:?1?})
?},?1000)
?}).then((data)?=>?{
?console.log('result1',?data)
?//dosomething
?return?test()
?}).then((data)?=>?{
?console.log('result2',?data)
?})
?function?test(id)?{
?return?new?Promise(((resolve,?reject)?=>?{
?setTimeout(()?=>?{
?resolve({?test:?2?})
?},?5000)
?}))
?}
?//result1?{?test:?1?}
?//result2?{?test:?2?}
復(fù)制代碼

顯然,新增的邏輯就是針對 resolve 入?yún)?Promise 的時候的處理。我們觀察一下 test 里面創(chuàng)建的 Promise,它是沒有調(diào)用 then方法的。從上面的分析我們已經(jīng)知道 Promise 的回調(diào)函數(shù)就是通過調(diào)用其 then 方法注冊的,因此 test 里面創(chuàng)建的 Promise 其回調(diào)函數(shù)為空。

顯然如果沒有回調(diào)函數(shù),執(zhí)行 resolve 的時候,是沒辦法鏈?zhǔn)较氯サ摹R虼耍覀冃枰鲃訛槠渥⑷牖卣{(diào)函數(shù)。

我們只要把第一個 then 中產(chǎn)生的 Promise 的 resolve 函數(shù)的執(zhí)行,延遲到 test 里面的 Promise 的狀態(tài)為 onFulfilled 的時候再執(zhí)行,那么鏈?zhǔn)骄涂梢岳^續(xù)了。所以,當(dāng) resolve 入?yún)?Promise 的時候,調(diào)用其 then 方法為其注入回調(diào)函數(shù),而注入的是前一個 Promise 的 resolve 方法,所以要用 call 來綁定 this 的指向。

基于新的 Promise 模型,上面的執(zhí)行過程產(chǎn)生的 Promise 實例及其回調(diào)函數(shù),可以用看下表:

Promise callback P1 [{onFulfilled:c1(第一個then中的fn),resolve:p2resolve}] P2 (P1 調(diào)用 then 時產(chǎn)生) [{onFulfilled:c2(第二個then中的fn),resolve:p3resolve}] P3 (P2 調(diào)用 then 時產(chǎn)生) [] P4 (執(zhí)行c1中產(chǎn)生[調(diào)用 test ]) [{onFulfilled:p2resolve,resolve:p5resolve}] P5 (調(diào)用p2resolve 時,進入 then.call 邏輯中產(chǎn)生) [] 有了這個表格,我們就可以清晰知道各個實例中 callback 執(zhí)行的順序是:

c1 -> p2resolve -> c2 -> p3resolve -> [] -> p5resolve -> []

以上就是鏈?zhǔn)秸{(diào)用的原理了。

reject

下面我們再來補全 reject 的邏輯。只需要在注冊回調(diào)、狀態(tài)改變時加上 reject 的邏輯即可。

完整代碼如下:

?function?Promise(fn){?
?let?state?=?'pending';
?let?value?=?null;
?const?callbacks?=?[];
?this.then?=?function?(onFulfilled,onRejected){
?return?new?Promise((resolve,?reject)=>{
?handle({
?onFulfilled,?
?onRejected,
?resolve,?
?reject
?})
?})
?}
?function?handle(callback){
?if(state?===?'pending'){
?callbacks.push(callback)
?return;
?}
?
?const?cb?=?state?===?'fulfilled'???callback.onFulfilled:callback.onRejected;
?const?next?=?state?===?'fulfilled'??callback.resolve:callback.reject;
?if(!cb){
?next(value)
?return;
?}
?const?ret?=?cb(value)
?next(ret)
?}
?function?resolve(newValue){
?const?fn?=?()=>{
?if(state?!==?'pending')return
?if(newValue?&&?(typeof?newValue?===?'object'?||?typeof?newValue?===?'function')){
?const?{then}?=?newValue
?if(typeof?then?===?'function'){
?//?newValue?為新產(chǎn)生的?Promise,此時resolve為上個?promise?的resolve
?//相當(dāng)于調(diào)用了新產(chǎn)生?Promise?的then方法,注入了上個?promise?的resolve?為其回調(diào)
?then.call(newValue,resolve,?reject)
?return
?}
?}
?state?=?'fulfilled';
?value?=?newValue
?handelCb()
?}
?
?setTimeout(fn,0)
?}
?function?reject(error){
?const?fn?=?()=>{
?if(state?!==?'pending')return
?if(error?&&?(typeof?error?===?'object'?||?typeof?error?===?'function')){
?const?{then}?=?error
?if(typeof?then?===?'function'){
?then.call(error,resolve,?reject)
?return
?}
?}
?state?=?'rejected';
?value?=?error
?handelCb()
?}
?setTimeout(fn,0)
?}
?function?handelCb(){
?while(callbacks.length)?{
?const?fn?=?callbacks.shift();
?handle(fn);
?};
?}
?fn(resolve,?reject)
?}
復(fù)制代碼

異常處理

異常通常是指在執(zhí)行成功/失敗回調(diào)時代碼出錯產(chǎn)生的錯誤,對于這類異常,我們使用 try-catch 來捕獲錯誤,并將 Promise 設(shè)為 rejected 狀態(tài)即可。

handle代碼改造如下:

?function?handle(callback){
?if(state?===?'pending'){
?callbacks.push(callback)
?return;
?}
?
?const?cb?=?state?===?'fulfilled'???callback.onFulfilled:callback.onRejected;
?const?next?=?state?===?'fulfilled'??callback.resolve:callback.reject;
?if(!cb){
?next(value)
?return;
?}
?try?{
?const?ret?=?cb(value)
?next(ret)
?}?catch?(e)?{
?callback.reject(e);
?}?
?}
復(fù)制代碼

我們實際使用時,常習(xí)慣注冊 catch 方法來處理錯誤,例:

?new?Promise((resolve,?reject)?=>?{
?setTimeout(()?=>?{
?resolve({?test:?1?})
?},?1000)
?}).then((data)?=>?{
?console.log('result1',?data)
?//dosomething
?return?test()
?}).catch((ex)?=>?{
?console.log('error',?ex)
?})
復(fù)制代碼

實際上,錯誤也好,異常也罷,最終都是通過reject實現(xiàn)的。也就是說可以通過 then 中的錯誤回調(diào)來處理。所以我們可以增加這樣的一個 catch 方法:

?function?Promise(fn){?
?...
?this.then?=?function?(onFulfilled,onRejected){
?return?new?Promise((resolve,?reject)=>{
?handle({
?onFulfilled,?
?onRejected,
?resolve,?
?reject
?})
?})
?}
?this.catch?=?function?(onError){
?this.then(null,onError)
?}
?...
?}
復(fù)制代碼

Finally方法

在實際應(yīng)用的時候,我們很容易會碰到這樣的場景,不管Promise最后的狀態(tài)如何,都要執(zhí)行一些最后的操作。我們把這些操作放到 finally 中,也就是說 finally 注冊的函數(shù)是與 Promise 的狀態(tài)無關(guān)的,不依賴 Promise 的執(zhí)行結(jié)果。所以我們可以這樣寫 finally 的邏輯:

?function?Promise(fn){?
?...
?this.catch?=?function?(onError){
?this.then(null,onError)
?}
?this.finally?=?function?(onDone){
?this.then(onDone,onDone)
?}
?...
?}
復(fù)制代碼

resolve 方法和 reject 方法

實際應(yīng)用中,我們可以使用 Promise.resolve 和 Promise.reject 方法,用于將于將非 Promise 實例包裝為 Promise 實例。如下例子:

Promise.resolve({name:'winty'})
Promise.reject({name:'winty'})
//?等價于
new?Promise(resolve?=>?resolve({name:'winty'}))
new?Promise((resolve,reject)?=>?reject({name:'winty'}))
復(fù)制代碼

這些情況下,Promise.resolve 的入?yún)⒖赡苡幸韵聨追N情況:

  • 無參數(shù) [直接返回一個resolved狀態(tài)的 Promise 對象]

  • 普通數(shù)據(jù)對象 [直接返回一個resolved狀態(tài)的 Promise 對象]

  • 一個Promise實例 [直接返回當(dāng)前實例]

  • 一個thenable對象(thenable對象指的是具有then方法的對象) [轉(zhuǎn)為 Promise 對象,并立即執(zhí)行thenable對象的then方法。]

基于以上幾點,我們可以實現(xiàn)一個 Promise.resolve 方法如下:

?function?Promise(fn){?
?...
?this.resolve?=?function?(value){
?if?(value?&&?value?instanceof?Promise)?{
?return?value;
?}?else?if?(value?&&?typeof?value?===?'object'?&&?typeof?value.then?===?'function'){
?let?then?=?value.then;
?return?new?Promise(resolve?=>?{
?then(resolve);
?});
?}?else?if?(value)?{
?return?new?Promise(resolve?=>?resolve(value));
?}?else?{
?return?new?Promise(resolve?=>?resolve());
?}
?}
?...
?}
復(fù)制代碼

Promise.reject與Promise.resolve類似,區(qū)別在于Promise.reject始終返回一個狀態(tài)的rejected的Promise實例,而Promise.resolve的參數(shù)如果是一個Promise實例的話,返回的是參數(shù)對應(yīng)的Promise實例,所以狀態(tài)不一 定。 因此,reject 的實現(xiàn)就簡單多了,如下:

?function?Promise(fn){?
?...
?this.reject?=?function?(value){
?return?new?Promise(function(resolve,?reject)?{
				reject(value);
			});
?}
?...
?}
復(fù)制代碼

Promise.all

入?yún)⑹且粋€ Promise 的實例數(shù)組,然后注冊一個 then 方法,然后是數(shù)組中的 Promise 實例的狀態(tài)都轉(zhuǎn)為 fulfilled 之后則執(zhí)行 then 方法。這里主要就是一個計數(shù)邏輯,每當(dāng)一個 Promise 的狀態(tài)變?yōu)?fulfilled 之后就保存該實例返回的數(shù)據(jù),然后將計數(shù)減一,當(dāng)計數(shù)器變?yōu)?0 時,代表數(shù)組中所有 Promise 實例都執(zhí)行完畢。

?function?Promise(fn){?
?...
?this.all?=?function?(arr){
?var?args?=?Array.prototype.slice.call(arr);
?return?new?Promise(function(resolve,?reject)?{
?if(args.length?===?0)?return?resolve([]);
?var?remaining?=?args.length;
?function?res(i,?val)?{
?try?{
?if(val?&&?(typeof?val?===?'object'?||?typeof?val?===?'function'))?{
?var?then?=?val.then;
?if(typeof?then?===?'function')?{
?then.call(val,?function(val)?{
?res(i,?val);
?},?reject);
?return;
?}
?}
?args[i]?=?val;
?if(--remaining?===?0)?{
?resolve(args);
?}
?}?catch(ex)?{
?reject(ex);
?}
?}
?for(var?i?=?0;?i?<?args.length;?i++)?{
?res(i,?args[i]);
?}
?});
?}
?...
?}
復(fù)制代碼

Promise.race

有了 Promise.all 的理解,Promise.race 理解起來就更容易了。它的入?yún)⒁彩且粋€ Promise 實例數(shù)組,然后其 then 注冊的回調(diào)方法是數(shù)組中的某一個 Promise 的狀態(tài)變?yōu)?fulfilled 的時候就執(zhí)行。因為 Promise 的狀態(tài)只能改變一次,那么我們只需要把 Promise.race 中產(chǎn)生的 Promise 對象的 resolve 方法,注入到數(shù)組中的每一個 Promise 實例中的回調(diào)函數(shù)中即可。

function?Promise(fn){?
?...
?this.race?=?function(values)?{
?return?new?Promise(function(resolve,?reject)?{
?for(var?i?=?0,?len?=?values.length;?i?<?len;?i++)?{
?values[i].then(resolve,?reject);
?}
?});
?}
?...
?}?
復(fù)制代碼

總結(jié)

Promise 源碼不過幾百行,我們可以從執(zhí)行結(jié)果出發(fā),分析每一步的執(zhí)行過程,然后思考其作用即可。其中最關(guān)鍵的點就是要理解 then 函數(shù)是負(fù)責(zé)注冊回調(diào)的,真正的執(zhí)行是在 Promise 的狀態(tài)被改變之后。而當(dāng) resolve 的入?yún)⑹且粋€ Promise 時,要想鏈?zhǔn)秸{(diào)用起來,就必須調(diào)用其 then 方法(then.call),將上一個 Promise 的 resolve 方法注入其回調(diào)數(shù)組中。

補充說明

雖然 then 普遍認(rèn)為是微任務(wù)。但是瀏覽器沒辦法模擬微任務(wù),目前要么用 setImmediate ,這個也是宏任務(wù),且不兼容的情況下還是用 setTimeout 打底的。還有,promise 的 polyfill (es6-promise) 里用的也是 setTimeout。因此這里就直接用 setTimeout,以宏任務(wù)來代替微任務(wù)了。

參考資料

  • PromiseA+規(guī)范

  • Promise 實現(xiàn)原理精解

  • 30分鐘,讓你徹底明白Promise原理

完整 Promise 模型

function?Promise(fn)?{
?let?state?=?'pending'
?let?value?=?null
?const?callbacks?=?[]
?this.then?=?function?(onFulfilled,?onRejected)?{
?return?new?Promise((resolve,?reject)?=>?{
?handle({
?onFulfilled,
?onRejected,
?resolve,
?reject,
?})
?})
?}
?this.catch?=?function?(onError)?{
?this.then(null,?onError)
?}
?this.finally?=?function?(onDone)?{
?this.then(onDone,?onError)
?}
?this.resolve?=?function?(value)?{
?if?(value?&&?value?instanceof?Promise)?{
?return?value
?}?if?(value?&&?typeof?value?===?'object'?&&?typeof?value.then?===?'function')?{
?const?{?then?}?=?value
?return?new?Promise((resolve)?=>?{
?then(resolve)
?})
?}?if?(value)?{
?return?new?Promise(resolve?=>?resolve(value))
?}
?return?new?Promise(resolve?=>?resolve())
?}
?this.reject?=?function?(value)?{
?return?new?Promise(((resolve,?reject)?=>?{
?reject(value)
?}))
?}
?this.all?=?function?(arr)?{
?const?args?=?Array.prototype.slice.call(arr)
?return?new?Promise(((resolve,?reject)?=>?{
?if?(args.length?===?0)?return?resolve([])
?let?remaining?=?args.length
?function?res(i,?val)?{
?try?{
?if?(val?&&?(typeof?val?===?'object'?||?typeof?val?===?'function'))?{
?const?{?then?}?=?val
?if?(typeof?then?===?'function')?{
?then.call(val,?(val)?=>?{
?res(i,?val)
?},?reject)
?return
?}
?}
?args[i]?=?val
?if?(--remaining?===?0)?{
?resolve(args)
?}
?}?catch?(ex)?{
?reject(ex)
?}
?}
?for?(let?i?=?0;?i?<?args.length;?i++)?{
?res(i,?args[i])
?}
?}))
?}
?this.race?=?function?(values)?{
?return?new?Promise(((resolve,?reject)?=>?{
?for?(let?i?=?0,?len?=?values.length;?i?<?len;?i++)?{
?values[i].then(resolve,?reject)
?}
?}))
?}
?function?handle(callback)?{
?if?(state?===?'pending')?{
?callbacks.push(callback)
?return
?}
?const?cb?=?state?===?'fulfilled'???callback.onFulfilled?:?callback.onRejected
?const?next?=?state?===?'fulfilled'???callback.resolve?:?callback.reject
?if?(!cb)?{
?next(value)
?return
?}
?try?{
?const?ret?=?cb(value)
?next(ret)
?}?catch?(e)?{
?callback.reject(e)
?}
?}
?function?resolve(newValue)?{
?const?fn?=?()?=>?{
?if?(state?!==?'pending')?return
?if?(newValue?&&?(typeof?newValue?===?'object'?||?typeof?newValue?===?'function'))?{
?const?{?then?}?=?newValue
?if?(typeof?then?===?'function')?{
?//?newValue?為新產(chǎn)生的?Promise,此時resolve為上個?promise?的resolve
?//?相當(dāng)于調(diào)用了新產(chǎn)生?Promise?的then方法,注入了上個?promise?的resolve?為其回調(diào)
?then.call(newValue,?resolve,?reject)
?return
?}
?}
?state?=?'fulfilled'
?value?=?newValue
?handelCb()
?}
?setTimeout(fn,?0)
?}
?function?reject(error)?{
?const?fn?=?()?=>?{
?if?(state?!==?'pending')?return
?if?(error?&&?(typeof?error?===?'object'?||?typeof?error?===?'function'))?{
?const?{?then?}?=?error
?if?(typeof?then?===?'function')?{
?then.call(error,?resolve,?reject)
?return
?}
?}
?state?=?'rejected'
?value?=?error
?handelCb()
?}
?setTimeout(fn,?0)
?}
?function?handelCb()?{
?while?(callbacks.length)?{
?const?fn?=?callbacks.shift()
?handle(fn)
?}
?}
?fn(resolve,?reject)
}

這一次,徹底弄懂 Promise

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

當(dāng)前題目:這一次,徹底弄懂Promise-創(chuàng)新互聯(lián)
文章URL:http://www.chinadenli.net/article24/degdce.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)做網(wǎng)站建站公司標(biāo)簽優(yōu)化電子商務(wù)網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)