Promise/A+ 規(guī)范的實現(xiàn)


官方文檔地址 https://promisesaplus.com/
本文不涉及具體用法冕杠,只從具體實現(xiàn)上出發(fā)

第一步钠糊,實現(xiàn)同步版的promise

promise包含幾個關(guān)鍵詞:

  • resolve
  • reject
  • then

其中resolve和reject的代碼在正常使用的時候是看不到的俺亮,但可以猜測他們兩個都應(yīng)該是回調(diào)函數(shù)戚炫,傳遞給了用戶傳入的函數(shù)扬跋,而then則掛在原型上

結(jié)構(gòu)如下:

calss Promise{
    consturctor(exector){
        function resolve(){
            
        }
        function reject(){

        }
        exector(resolve,reject)
    }
    then(){

    }
}

文檔中提出园细,promise具備三種邏輯判斷狀態(tài)pending、fulfilled昔馋、rejected,三者不并處糖耸,同一時間只能存在一種狀態(tài)

pending向fulfilled或rejected單向流動秘遏。

同步版本實現(xiàn)

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class Promise{
    constructor(exector){
        let self = this;
        self.status = PENDING;
        self.value = undefined;
        self.reason = undefined;
        let resolve = (value)=>{
            if(self.status === PENDING){
                self.status = FULFILLED
                self.value = value;
            }
        }
        let reject = (reason)=>{
            if(self.status === PENDING){
                self.status = REJECTED;
                self.reason = reason
            }
        }
        try{
            exector(resolve,reject)
        }catch(e){
            reject(e)
        }
    }
    then(onFulfilled,onRejected){
        let self = this;
        if(self.status === FULFILLED){
            onFulfilled(self.value);
        }
        if(self.status === REJECTED){
            onRejected(self.reason);
        }
    }
};

現(xiàn)在測試一下:

new Promise((resolve,reject)=>{
    reject("1");
}).then((data)=>{
    console.log(data)
},(reason)=>{
    console.log(reason)
})

resolve和reject都能夠得到準確輸出

存在的問題

異步不支持

new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(2)
    })
}).then((data)=>{
    console.log(data)
},(reason)=>{
    console.log(reason)
})

現(xiàn)在用setTimeout包裹resolve,結(jié)果就是什么輸出也沒有

同步的話嘉竟,resolve先執(zhí)行邦危,onFulfilled后執(zhí)行,此時狀態(tài)已經(jīng)變成了fulfilled

異步的話舍扰,then先執(zhí)行倦蚪,此時status還是pending,無法進入fulfilled狀態(tài)边苹,所以onFulfilled不會執(zhí)行陵且,setTimeout之后resolve改變status,但已經(jīng)找不到onFulfilled了

then沒有容錯

new Promise((resolve,reject)=>{
    resolve(2)
}).then()

像上面這種情況个束,如果沒有給then方法傳遞參數(shù)慕购,那么程序會報錯

解決存在的問題

異步promise

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class Promise{
    constructor(exector){
        let self = this;
        self.status = PENDING;
        self.value = undefined;
        self.reason = undefined;
        self.onResolveCallBacks = [];
        self.onRejectCallBacks = [];
        let resolve = (value)=>{
            if(self.status === PENDING){
                self.status = FULFILLED
                self.value = value;
                self.onResolveCallBacks.forEach(cb=>cb(self.value));
            }
        }
        let reject = (reason)=>{
            if(self.status === PENDING){
                self.status = REJECTED;
                self.reason = reason
                self.onRejectCallBacks.forEach(cb=>cb(self.reason));
            }
        }
        try{
            exector(resolve,reject)
        }catch(e){
            reject(e)
        }
    }
    then(onFulfilled,onRejected){
        let self = this;
        if(self.status === FULFILLED){
            onFulfilled(self.value);
        }
        if(self.status === REJECTED){
            onRejected(self.reason);
        }
        if(self.status === PENDING){
            self.onResolveCallBacks.push(onFulfilled);
            self.onRejectCallBacks.push(onRejected);
        }
    }
};

因為resolve和then的執(zhí)行順序無法保證,所以要用訂閱發(fā)布的方式來實現(xiàn)茬底,所以創(chuàng)建兩個數(shù)組沪悲,分別存儲成功和失敗的回調(diào)函數(shù)

self.onResolveCallBacks = [];
self.onRejectCallBacks = [];

然后再改寫resolve和reject函數(shù),執(zhí)行發(fā)布

let resolve = (value)=>{
    if(self.status === PENDING){
        self.status = FULFILLED
        self.value = value;
        self.onResolveCallBacks.forEach(cb=>cb(self.value));
    }
}

此時進行測試:

new Promise((resolve,reject)=>{
    setTimeout(()=>{
        reject("失敗")
    },2000)
}).then((data)=>{
    console.log(data);
},(reason)=>{
    console.log(reason);
})

成功輸出失敗阱表,到此異步的promise完成了

then容錯

總錯這里不太好理解殿如,所以后面再做

第二步,Promise的鏈式調(diào)用

promise支持鏈式調(diào)用最爬,使用方法如:

new Promise((resolve,reject)=>{
    //resolve or reject
}).then((d)=>{
    return d
},(r)=>{
    return r
}).then((d)=>{
    return d
},(r)=>{
    return r
}).then((data)=>{
    console.log(data);
},(reason)=>{
    console.log(reason);
})

上面的.then中return后再then就是鏈式調(diào)用

前面知道promise實例具備then方法涉馁,所以如果我們的then方法執(zhí)行后,再返回一個Promise方法的話爱致,不就可以繼續(xù)進行.then了嗎谨胞?

同步鏈式調(diào)用

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class Promise{
    constructor(exector){
        let self = this;
        self.status = PENDING;
        self.value = undefined;
        self.reason = undefined;
        self.onResolveCallBacks = [];
        self.onRejectCallBacks = [];
        let resolve = (value)=>{
            if(self.status === PENDING){
                self.status = FULFILLED
                self.value = value;
                self.onResolveCallBacks.forEach(cb=>cb(self.value));
            }
        }
        let reject = (reason)=>{
            if(self.status === PENDING){
                self.status = REJECTED;
                self.reason = reason
                self.onRejectCallBacks.forEach(cb=>cb(self.reason));
            }
        }
        try{
            exector(resolve,reject)
        }catch(e){
            reject(e)
        }
    }
    then(onFulfilled,onRejected){
        // onFulfilled = typeof onFulfilled == 'function'?onFulfilled:value=>value;
        // onRejected = typeof onRejected == 'function'?onRejected:reason => {throw reason};
        let self = this;
        if(self.status === FULFILLED){
            return new Promise((resolve,reject)=>{
                let x = onFulfilled(self.value);
                resolve(x);
            })
        }
        if(self.status === REJECTED){
            return new Promise((resolve,reject)=>{   
            let x = onRejected(self.reason);
                reject(x);
            })
        }
        if(self.status === PENDING){
            self.onResolveCallBacks.push(onFulfilled);
            self.onRejectCallBacks.push(onRejected);
        }
    }
};

這里核心就是then方法返回了一個新的promise實例:

return new Promise((resolve,reject)=>{
    let x = onFulfilled(self.value);
    resolve(x);
})

1,pormise(p1)執(zhí)行resolve蒜鸡,改變status為fulfilled

2胯努,then方法執(zhí)行onFulfilled

3牢裳,onFulfilled返回一個新的promise,簡稱p2

4叶沛,由于p1是resolve蒲讯,所以p2也知行resolve

5,p2執(zhí)行灰署,改變了p2的status為fulfilled

6判帮,p2繼續(xù)執(zhí)行p2的onFulfilled

至此就做到了一個同步的鏈式調(diào)用

異步鏈式調(diào)用

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class Promise{
    constructor(exector){
        let self = this;
        self.status = PENDING;
        self.value = undefined;
        self.reason = undefined;
        self.onResolveCallBacks = [];
        self.onRejectCallBacks = [];
        let resolve = (value)=>{
            if(self.status === PENDING){
                self.status = FULFILLED
                self.value = value;
                self.onResolveCallBacks.forEach(cb=>cb(self.value));
            }
        }
        let reject = (reason)=>{
            if(self.status === PENDING){
                self.status = REJECTED;
                self.reason = reason
                self.onRejectCallBacks.forEach(cb=>cb(self.reason));
            }
        }
        try{
            exector(resolve,reject)
        }catch(e){
            reject(e)
        }
    }
    then(onFulfilled,onRejected){
        let self = this;
        if(self.status === FULFILLED){
            return new Promise((resolve,reject)=>{
                let x = onFulfilled(self.value);
                resolve(x);
            })
        }
        if(self.status === REJECTED){
            return new Promise((resolve,reject)=>{   
            let x = onRejected(self.reason);
                reject(x);
            })
        }
        if(self.status === PENDING){
            return new Promise(function(resolve,reject){
                self.onResolveCallBacks.push(function(){
                    let x = onFulfilled(self.value);
                    resolve(x);
                });
                self.onRejectCallBacks.push(function(){
                    let x = onRejected(self.reason);
                    reject(x);
                });
            })
        }
    }
};

這里的核心是當status為pending狀態(tài)時,同樣要立刻返回一個promise對象溉箕,否則沒有返回值的話晦墙,第二次鏈式調(diào)用的then方法根本不存在,需要仔細理解這里

if(self.status === PENDING){
    return new Promise(function(resolve,reject){
        self.onResolveCallBacks.push(function(){
            let x = onFulfilled(self.value);
            resolve(x);
        });
        self.onRejectCallBacks.push(function(){
            let x = onRejected(self.reason);
            reject(x);
        });
    })
}

第三步肴茄,鏈式調(diào)用其他的promise實現(xiàn)

經(jīng)過前面晌畅,我們已經(jīng)實現(xiàn)了一個鏈式調(diào)用的promise,但還存在一種情況寡痰,就是如果第一個onFulfilled返回一個Promise對像的話怎么處理

new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve(new Promise((resolve,reject)=>{
            resolve("10000");
        }))
    },3000)
}).then((d1)=>{
    console.log(d1);
    return d1
},(r1)=>{
    console.log(r1);
    return r1;
}).then((d2)=>{
    console.log(d2);
},(r2)=>{
    console.log(r2);
})

例如上面的情況抗楔,拿到的結(jié)果就出現(xiàn)了問題

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class Promise{
    constructor(exector){
        let self = this;
        self.status = PENDING;
        self.value = undefined;
        self.reason = undefined;
        self.onResolveCallBacks = [];
        self.onRejectCallBacks = [];
        let resolve = (value)=>{
            if(self.status === PENDING){
                self.status = FULFILLED
                self.value = value;
                self.onResolveCallBacks.forEach(cb=>cb(self.value));
            }
        }
        let reject = (reason)=>{
            if(self.status === PENDING){
                self.status = REJECTED;
                self.reason = reason
                self.onRejectCallBacks.forEach(cb=>cb(self.reason));
            }
        }
        try{
            exector(resolve,reject)
        }catch(e){
            reject(e)
        }
    }
    then(onFulfilled,onRejected){
        // onFulfilled = typeof onFulfilled == 'function'?onFulfilled:value=>value;
        // onRejected = typeof onRejected == 'function'?onRejected:reason => {throw reason};
        let self = this;
        if(self.status === FULFILLED){
            return new Promise((resolve,reject)=>{
                let x = onFulfilled(self.value);
                resolve(x);
            })
        }
        if(self.status === REJECTED){
            return new Promise((resolve,reject)=>{   
            let x = onRejected(self.reason);
                reject(x);
            })
        }
        if(self.status === PENDING){
            return new Promise(function(resolve,reject){
                self.onResolveCallBacks.push(function(){
                    let x = onFulfilled(self.value);
                    if(x instanceof Promise){
                        x.then(resolve,reject)
                    }else{
                        resolve(x);
                    }
                });
                self.onRejectCallBacks.push(function(){
                    let x = onRejected(self.reason);
                    if(x instanceof Promise){
                        x.then(resolve,reject);
                    }else{
                        reject(x);
                    }
                });
            })
        }
    }
};

這一次關(guān)鍵的代碼是

 return new Promise(function(resolve,reject){
    self.onResolveCallBacks.push(function(){
        let x = onFulfilled(self.value);
        if(x instanceof Promise){
            x.then(resolve,reject)
        }else{
            resolve(x);
        }
    });
    self.onRejectCallBacks.push(function(){
        let x = onRejected(self.reason);
        if(x instanceof Promise){
            x.then(resolve,reject);
        }else{
            reject(x);
        }
    });
})

1,通過instanceof判斷了x是否是promise對象

2拦坠,如果x是promise對象连躏,稱為p3

3,將p2的resolve當作p3的onFulfilled

4贞滨,當p3resolve的時候入热,實際之行的是p2的resolve

5,p2的resolve執(zhí)行的時候晓铆,會執(zhí)行第二次的then方法中添加進來的onFulfilled

繼續(xù)完善鏈式調(diào)用

new Promise((resolve,reject)=>{
    // setTimeout(()=>{
        resolve("成功")
    // },3000)/
}).then((d1)=>{
    console.log(d1);
    return new Promise((resolve,reject)=>{
        resolve(new Promise((resolve,reject)=>{
            resolve("111")
        }));
    })
},(r1)=>{
    console.log(r1);
    return r1;
}).then((d2)=>{
    console.log(d2);
},(r2)=>{
    console.log(r2);
})

例如上面這種才顿,多層promise對象不斷返回的場景

之前的寫法只能滿足一層需求

所以需要使用遞歸來實現(xiàn),除此之外還要考慮邊界問題尤蒿,至于邊界可以對照文檔來逐步實現(xiàn),全部實現(xiàn)代碼如下:

const PENDING =  'pending';//初始態(tài)
const FULFILLED =  'fulfilled';//初始態(tài)
const REJECTED =  'rejected';//初始態(tài)
function Promise(executor){
  let self = this;//先緩存當前promise實例
  self.status = PENDING;//設(shè)置狀態(tài)
  //定義存放成功的回調(diào)的數(shù)組
  self.onResolvedCallbacks = [];
  //定義存放失敗回調(diào)的數(shù)組
  self.onRejectedCallbacks = [];
  //當調(diào)用此方法的時候郑气,如果promise狀態(tài)為pending,的話可以轉(zhuǎn)成成功態(tài),如果已經(jīng)是成功態(tài)或者失敗態(tài)了,則什么都不做
  //2.1
  function resolve(value){ //2.1.1
    if(value!=null &&value.then&&typeof value.then == 'function'){
      return value.then(resolve,reject);
    }
    //如果是初始態(tài)腰池,則轉(zhuǎn)成成功態(tài)
    //為什么要把它用setTimeout包起來
    setTimeout(function(){
      if(self.status == PENDING){
        self.status = FULFILLED;
        self.value = value;//成功后會得到一個值尾组,這個值不能改
        //調(diào)用所有成功的回調(diào)
        self.onResolvedCallbacks.forEach(cb=>cb(self.value));
      }
    })

  }
  function reject(reason){ //2.1.2
    setTimeout(function(){
      //如果是初始態(tài),則轉(zhuǎn)成失敗態(tài)
      if(self.status == PENDING){
        self.status = REJECTED;
        self.value = reason;//失敗的原因給了value
        self.onRejectedCallbacks.forEach(cb=>cb(self.value));
      }
    });

  }
  try{
    //因為此函數(shù)執(zhí)行可能會異常示弓,所以需要捕獲讳侨,如果出錯了,需要用錯誤 對象reject
    executor(resolve,reject);
  }catch(e){
    //如果這函數(shù)執(zhí)行失敗了奏属,則用失敗的原因reject這個promise
    reject(e);
  };
}
function resolvePromise(promise2,x,resolve,reject){
  if(promise2 === x){
    return reject(new TypeError('循環(huán)引用'));
  }
  let called = false;//promise2是否已經(jīng)resolve 或reject了
  if(x instanceof Promise){
    if(x.status == PENDING){
      x.then(function(y){
        resolvePromise(promise2,y,resolve,reject);
      },reject);
    }else{
      x.then(resolve,reject);
    }
  //x是一個thenable對象或函數(shù)跨跨,只要有then方法的對象,
  }else if(x!= null &&((typeof x=='object')||(typeof x == 'function'))){
    //當我們的promise和別的promise進行交互,編寫這段代碼的時候盡量的考慮兼容性勇婴,允許別人瞎寫
   try{
     let then = x.then;
     if(typeof then == 'function'){
       //有些promise會同時執(zhí)行成功和失敗的回調(diào)
       then.call(x,function(y){
         //如果promise2已經(jīng)成功或失敗了忱嘹,則不會再處理了
          if(called)return;
          called = true;
          resolvePromise(promise2,y,resolve,reject)
       },function(err){
         if(called)return;
         called = true;
         reject(err);
       });
     }else{
       //到此的話x不是一個thenable對象,那直接把它當成值resolve promise2就可以了
       resolve(x);
     }
   }catch(e){
     if(called)return;
     called = true;
     reject(e);
   }

  }else{
    //如果X是一個普通 的值耕渴,則用x的值去resolve promise2
    resolve(x);
  }
}
//onFulfilled 是用來接收promise成功的值或者失敗的原因
Promise.prototype.then = function(onFulfilled,onRejected){
  //如果成功和失敗的回調(diào)沒有傳拘悦,則表示這個then沒有任何邏輯,只會把值往后拋
  //2.2.1
  onFulfilled = typeof onFulfilled == 'function'?onFulfilled:function(value){return  value};
  onRejected = typeof onRejected == 'function'?onRejected:reason=>{throw reason};
  //如果當前promise狀態(tài)已經(jīng)是成功態(tài)了橱脸,onFulfilled直接取值
  let self = this;
  let promise2;
  if(self.status == FULFILLED){
    return promise2 = new Promise(function(resolve,reject){
      setTimeout(function(){
        try{
          let x =onFulfilled(self.value);
          //如果獲取到了返回值x,會走解析promise的過程
          resolvePromise(promise2,x,resolve,reject);
        }catch(e){
          //如果執(zhí)行成功的回調(diào)過程中出錯了础米,用錯誤原因把promise2 reject
          reject(e);
        }
      })

    });
  }
  if(self.status == REJECTED){
    return promise2 = new Promise(function(resolve,reject){
      setTimeout(function(){
        try{
          let x =onRejected(self.value);
          resolvePromise(promise2,x,resolve,reject);
        }catch(e){
          reject(e);
        }
      })
    });
  }
  if(self.status == PENDING){
   return promise2 = new Promise(function(resolve,reject){
     self.onResolvedCallbacks.push(function(){
         try{
           let x =onFulfilled(self.value);
           //如果獲取到了返回值x,會走解析promise的過程
           resolvePromise(promise2,x,resolve,reject);
         }catch(e){
           reject(e);
         }

     });
     self.onRejectedCallbacks.push(function(){
         try{
           let x =onRejected(self.value);
           resolvePromise(promise2,x,resolve,reject);
         }catch(e){
           reject(e);
         }
     });
   });
  }
}
module.exports = Promise;

主要是通過resolvePromise方法將具體的遞歸,以及邊界問題全部處理完畢

第四步添诉,promise api實現(xiàn)

Promise.all

接收一個數(shù)組屁桑,全部成功后才返回

Promise.all = function(arr){
    return new Promise((resolve,reject)=>{
        let resolvList=[];
        arr.forEach((item)=>{
            item.then((data)=>{
                resolvList.push(data);
                console.log(data);
                if(arr.length == resolvList.length){
                    resolve(resolvList);
                }
            },(reason)=>{
                reject(reason);
            })
        })
    })
}

Promise.race

接受一個數(shù)組,一個成功即返回

Promise.race = function(arr){
    return new Promise((resolve,reject)=>{
        arr.forEach((item)=>{
            item.then((data)=>{
                resolve(data);
            },(reason)=>{
                reject(reason);
            })
        })
    })
}

Promise.resolve

立刻返回一個promise對象栏赴,一般用于沒有promise對象蘑斧,需要將一個東西,轉(zhuǎn)為promise

Promise.resolve = function(value){
    return new Promise(function(resolve){
      resolve(value);
    });
  }

Promise.reject

立刻返回一個promise對象艾帐,一般用于沒有promise對象,需要將一個東西盆偿,轉(zhuǎn)為promise

Promise.reject = function(reason){
  return new Promise(function(resolve,reject){
    reject(reason);
  });
}

終于把這篇寫個大概了柒爸,待過一段時間再回顧一遍這個知識,加油事扭!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末捎稚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子求橄,更是在濱河造成了極大的恐慌今野,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罐农,死亡現(xiàn)場離奇詭異条霜,居然都是意外死亡,警方通過查閱死者的電腦和手機涵亏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門宰睡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人气筋,你說我怎么就攤上這事拆内。” “怎么了宠默?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵麸恍,是天一觀的道長。 經(jīng)常有香客問我搀矫,道長抹沪,這世上最難降的妖魔是什么刻肄? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮采够,結(jié)果婚禮上肄方,老公的妹妹穿的比我還像新娘。我一直安慰自己蹬癌,他們只是感情好权她,可當我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著逝薪,像睡著了一般隅要。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上董济,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天步清,我揣著相機與錄音,去河邊找鬼虏肾。 笑死廓啊,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的封豪。 我是一名探鬼主播谴轮,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吹埠!你這毒婦竟也來了第步?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤缘琅,失蹤者是張志新(化名)和其女友劉穎粘都,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刷袍,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡翩隧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了呻纹。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸽心。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖居暖,靈堂內(nèi)的尸體忽然破棺而出顽频,到底是詐尸還是另有隱情,我是刑警寧澤太闺,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布糯景,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蟀淮。R本人自食惡果不足惜最住,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怠惶。 院中可真熱鬧涨缚,春花似錦、人聲如沸策治。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽通惫。三九已至茂翔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間履腋,已是汗流浹背珊燎。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留遵湖,地道東北人悔政。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像延旧,于是被迫代替她去往敵國和親谋国。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Promise 對象 Promise 的含義 Promise 是異步編程的一種解決方案垄潮,比傳統(tǒng)的解決方案——回調(diào)函...
    neromous閱讀 8,711評論 1 56
  • 本文適用的讀者 本文寫給有一定Promise使用經(jīng)驗的人烹卒,如果你還沒有使用過Promise闷盔,這篇文章可能不適合你弯洗,...
    HZ充電大喵閱讀 7,313評論 6 19
  • 00牡整、前言Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強大溺拱。它由社區(qū)...
    夜幕小草閱讀 2,135評論 0 12
  • 排版很不友好逃贝,抱歉 /* * 實現(xiàn)Promise是根據(jù)Promise規(guī)范來的:https://promisesap...
    Egde閱讀 1,496評論 0 0
  • 前言 本文旨在簡單講解一下javascript中的Promise對象的概念,特性與簡單的使用方法迫摔。并在文末會附上一...
    _暮雨清秋_閱讀 2,202評論 0 3