本文根據promise的用法, 帶您一步一步的瞭解promise的源碼內幕; 本文采用要點、使用、源碼分析的思路,步步爲營,一點一點的剖析Promise的神祕世界;
本文Promise源碼部分採用es5語法
es6
ES6 規定,Promise對象是一個構造函數,用來生成Promise實例json
let p = new Promise();
複製代碼
function Promise(){ //... }
複製代碼
Promise構造函數接收一個執行器函數(executor)做爲參數, 該函數的兩個參數分別爲resolve和reject。當new生成對象實例的時候,Promise的參數executor會當即執行數組
let p = new Promise((resolve, reject)=>{
// coding....
});
複製代碼
function Promise(executor){
executor(resolve, reject); // 該函數會在new Promise()實例時當即調用,它接收兩個參數: resolve reject
}
複製代碼
(resolve, reject)=>{ // coding... }
, 調用時會傳遞兩個參數進去, 供// coding....處使用執行器executor的參數(resolve, reject)是兩個函數, 這兩函數的做用:promise
- resolve函數是將Promise對象的狀態從"pending"變爲"resolved"('未完成' => '成功'), 在異步操做成功時調用,並將異步操做結果做爲參數傳遞出去(源碼的resolve函數中接收);
- reject函數 是將Promise對象的狀態從"pending"變爲"rejected"('未完成' => '失敗'), 在異步操做失敗時調用,並將異步操做報出的錯誤,做爲參數傳遞出去(源碼的reject函數中接收);
let p = new Promise((resolve, reject)=>{
// coding....
resolve('成功');
// 或 reject('失敗');
});
複製代碼
function Promise(executor){
function resolve(value){
console.log(value); // 調用resolve('成功'); => 成功
}
function reject(reason){
console.log(reason); // 調用reject('失敗'); => 失敗
}
executor(resolve, reject); // 該函數會在new Promise()實例時當即調用,它接收兩個參數: resolve reject
}
複製代碼
// 升級(添加狀態)
function Promise(executor){
this.status = 'pending'; // 用於保存promise實例的狀態,默認爲pending,等待態
this.value = undefined; // 保存成功時的值
this.reason = undefined; // 保存失敗時的緣由
function resolve(value){
console.log(value); // 調用resolve('成功'); => 成功
this.value = value;
}
function reject(reason){
console.log(reason); // 調用reject('失敗'); => 失敗
this.reason = reason;
}
executor(resolve, reject); // 該函數會在new Promise()實例時當即調用,它接收兩個參數: resolve reject
}
複製代碼
// 升級(狀態的轉變) pending => fulfilled 或 pending => rejected
//一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。Promise對象的狀態改變,只有兩種可能:從pending變爲fulfilled和從pending變爲rejected。只要這兩種狀況發生,狀態就凝固了,不會再變了,會一直保持這個結果,這時就稱爲 resolved(已定型)。若是改變已經發生了,你再對Promise對象添加回調函數,也會當即獲得這個結果[摘自:http://es6.ruanyifeng.com/#docs/promise]
function Promise(executor){
let self = this;
this.status = 'pending'; // pending => fulfilled | rejected
this.value = undefined;
this.reason = undefined;
// 成功
function resolve(value){
if(self.status === 'pending'){
self.value = value;
self.status = 'fulfilled';
console.log(self.status)
}
}
function reject(reason){
if(self.status === 'pending'){
self.reason = reason;
self.status = 'rejected';
console.log(self.reason)
}
}
// 須要經過別名引用的方式; 由於resolve和reject中的this指向的是全局對象
executor(resolve, reject); // 該函數會在new Promise()實例時當即調用,它接收兩個參數: resolve reject
}
複製代碼
解析:bash
小結: 代碼書寫到此刻,咱們打印Promise實例, 便可查看到當前實例的狀態和相關屬性;異步
let p = new Promise((resolve, reject)=>{
resolve('成功');
/*
if (/* 異步操做成功 */){
resolve(value);
} else {
reject(error);
}
*/
});
console.log(p); // Promise { status: 'fulfilled', value: '成功', reason: undefined }
複製代碼
若是Promise的執行器函數(executor)裏面直接拋出異常呢? 捕獲錯誤,相對於執行了reject函數
let p = new Promise((resolve, reject)=>{
throw new Error('錯誤扔給你, 來打我呀^_^');
});
複製代碼
function Promise (executor){
// 在promise內部定義一個狀態 當前promise的狀態
let self = this;
self.value = undefined;
self.reason = undefined
self.status = 'pending'; // 默認promise的狀態是pengding
self.onResolevedCallbacks = []; // 存放全部成功的回調
self.onRejectedCallbacks = []; // 存放全部失敗的回調
function resolve(value){
// (value!=null && typeof value === 'object') || typeof value == 'function'
if(value instanceof Promise){
console.log('here');
// if(value.then && typeof value.then === 'function'){
return value.then((data)=>{
console.log('11111111111')
console.log(data)
resolve(data)
},y=>{
reject(y);
});
// }
}
console.log(self.status)
if(self.status === 'pending'){
self.value = value;
console.log('pending:',value)
self.status = 'resolved'; // 成功態
console.log('pending--', self.onResolevedCallbacks)
self.onResolevedCallbacks.forEach(fn=>fn());
}
}
function reject(reason){
if(self.status === 'pending'){
self.reason = reason;
self.status = 'rejected'; // 失敗態
// 發佈
self.onRejectedCallbacks.forEach(fn =>fn());
}
}
// ---------------修改在這裏-------------------------------------------------------------------------
// 小樣,敢給大爺拋錯誤, 直接捕獲了,讓你的錯誤銷聲匿跡 @<_>@
try{
executor(resolve,reject); // 用戶會調用resolve || reject
}catch(e){
reject(e); // 說明失敗了
}
}
複製代碼
上面代碼理解了,請移步下一個關 注意,爲了行文方便,後面的resolved統一隻指fulfilled狀態,不包含rejected狀態源碼分析
Promise.prototype.then()方法是Promise的核心方法; Promise實例生成之後,能夠用then方法分別指定resolved狀態和rejected狀態的回調函數;then方法的做用就是爲promise實例添加狀態改變時的回調函數;post
let p = new Promise((resolve, reject)=>{
resolve('成功');
// reject('失敗');
});
p.then((value)=>{
// 成功時執行的回調
console.log('執行resolve,輸出實例成功態的vlaue屬性: ', value);
}, (reason)=>{
// 失敗時執行的回調
console.log('執行reject,輸出實例失敗態的reason屬性: ', reason);
});
// => 執行resolve,輸出實例成功態的vlaue屬性: 成功
複製代碼
function Promise(executor){
let self = this;
self.status = 'pending'; // pending => fulfilled | rejected
self.value = undefined;
self.reason = undefined;
// 成功
function resolve(value){
if(self.status === 'pending'){
self.value = value;
self.status = 'fulfilled';
}
}
function reject(reason){
if(self.status === 'pending'){
self.reason = reason;
self.status = 'rejected';
}
}
try {
executor(resolve, reject); // 該函數會在new Promise()實例時當即調用,它接收兩個參數: resolve reject
}catch(err){
reject(err);
}
}
// Promise的核心方法
Promise.prototype.then = function(onFulfilled, onRejected){
if(this.status === 'fulfilled'){
onFulfilled(this.value); // 這裏傳遞成功的值
}
if(this.status === 'rejected'){
onRejected(this.reason); // 這裏傳遞失敗的緣由或錯誤
}
};
複製代碼
Promise.prototype.then() 與異步調用; 咱們知道Promise主要是用來處理異步的, 當promise對象的狀態在一段時間後發生變化時, 就會觸發then方法綁定的回調函數; 這裏要注意幾點:學習
1> then方法在調用時會當即執行(同步), 關鍵在於then不一樣狀態的回調函數只有在狀態發生改變時執行(異步);
2> Promise是同步的, 實例新建後會當即執行; then是異步的,當狀態改變時才執行
複製代碼
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
// => 依次輸出: 'Promise' 'Hi!' 'resolved.'
複製代碼
let p = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('成功'); // 2秒鐘以後,讓promise的狀態變成成功態
}, 2000);
});
p.then((value)=>{
// 成功時執行的回調
console.log('2秒後執行resolve,輸出實例成功態的vlaue屬性: ', value);
}, (reason)=>{
// 失敗時執行的回調
console.log('執行reject,輸出實例失敗態的reason屬性: ', reason);
});
複製代碼
function Promise(executor){
let self = this;
self.status = 'pending'; // pending => fulfilled | rejected
self.value = undefined;
self.reason = undefined;
self.onFulfilledCallbacks = []; // 用於存放全部then方法成功態的回調
self.onRejectedCallbacks = []; // 用於存放全部then方法失敗態的回調
// 成功
function resolve(value){
if(self.status === 'pending'){
self.value = value;
self.status = 'fulfilled';
self.onFulfilledCallbacks.forEach(fn=>fn()); // 當狀態變爲resolved時執行訂閱的函數(then方法成功時的回調)
}
}
function reject(reason){
if(self.status === 'pending'){
self.reason = reason;
self.status = 'rejected';
self.onRejectedCallbacks.forEach(fn=>fn()); // 當狀態變爲rejected時執行訂閱的函數(then方法失敗時的回調)
}
}
try {
executor(resolve, reject); // 該函數會在new Promise()實例時當即調用,它接收兩個參數: resolve reject
}catch(err){
reject(err);
}
}
Promise.prototype.then = function(onFulfilled, onRejected){
if(this.status === 'fulfilled'){
onFulfilled(this.value); // 這裏傳遞成功的值
}
if(this.status === 'rejected'){
onRejected(this.reason); // 這裏傳遞失敗的緣由或錯誤
}
// 在異步執行完成以前,promise的狀態爲pending,此時會把then兩種狀態的回調先存儲起來,待狀態改變後執行
if(this.status === 'pending'){
this.onFulfilledCallbacks.push(()=>{
onFulfilled(this.value);
});
this.onRejectedCallbacks.push(()=>{
onRejected(this.reason);
});
}
};
複製代碼
解析:
then方法返回的是一個新的Promise實例(該實例不是原來那個Promise實例);
let p = new Promise((resolve, reject)=>{
resolve(420);
});
p.then((value)=>{
// 成功時執行的回調
console.log('2秒後執行resolve,輸出實例成功態的vlaue屬性: ', value); // 2秒後執行resolve,輸出實例成功態的vlaue屬性: 420
return value + 100;
}, (reason)=>{
// 失敗時執行的回調
console.log('執行reject,輸出實例失敗態的reason屬性: ', reason);
}).then((value)=>{
// then的成功回調裏面輸出,前一個then成功回調的返回值(即promise實例的value屬性), 若是沒有顯示的return, 那麼返回的是undefined
console.log('第二個then的成功回調裏面輸出,前一個then成功回調的返回值: ',value); // 第二個then的成功回調裏面輸出,前一個then成功回調的返回值: 520
return value + 200;
}).then((value)=>{
console.log('第三個then的成功回調裏面輸出,前一個then成功回調的返回值: ',value); // 第三個then的成功回調裏面輸出,前一個then成功回調的返回值: 720
});
複製代碼
function Promise(executor){
let self = this;
self.status = 'pending'; // pending => fulfilled | rejected
self.value = undefined;
self.reason = undefined;
self.onFulfilledCallbacks = []; // 用於存放全部then方法成功態的回調
self.onRejectedCallbacks = []; // 用於存放全部then方法失敗態的回調
// 成功
function resolve(value){
if(self.status === 'pending'){
self.value = value;
self.status = 'fulfilled';
self.onFulfilledCallbacks.forEach(fn=>fn());
}
}
function reject(reason){
if(self.status === 'pending'){
self.reason = reason;
self.status = 'rejected';
self.onRejectedCallbacks.forEach(fn=>fn());
}
}
try {
executor(resolve, reject); // 該函數會在new Promise()實例時當即調用,它接收兩個參數: resolve reject
}catch(err){
reject(err);
}
}
Promise.prototype.then = function(onFulfilled, onRejected){
let self = this;
let promise2 = new Promise((resolve, reject)=>{
console.log(this === self); // 這裏由於使用了箭頭函數,因此self === this, 指向同一個對象; 爲了避免混淆,後面將採用self的方式
// 該executor函數會裏面執行,所以把以前的狀態判斷及成功回調的代碼移到此處與以前功能同樣;
// 須要說明的是這個promise須要根據上一個then的狀態和值進行判斷,故而設置self變量用於引用上一個this
if(this.status === 'fulfilled'){
let x = onFulfilled(this.value); // 成功回調; 這裏的value指的是第一個Promise實例的value屬性
resolve(x); // 將處理後的結果做爲參數傳遞給promise實例的value屬性; 同時也會傳遞給下一個then的成功回調
}
if(this.status === 'rejected'){
try{
let x = onRejected(this.reason); // onRejected處理
reject(x);
}catch(e){
reject(e);
}
}
if(this.status === 'pending'){
this.onFulfilledCallbacks.push(()=>{
onFulfilled(this.value);
});
this.onRejectedCallbacks.push(()=>{
onRejected(this.reason);
});
}
});
return promise2;
};
複製代碼
解析:
Promise.prototype.then() 與異步調用
let p = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve(420);
}, 3000);
});
p.then((value)=>{
// 成功時執行的回調
console.log('2秒後執行resolve,輸出實例成功態的vlaue屬性: ', value); // 2秒後執行resolve,輸出實例成功態的vlaue屬性: 420
return value + 100;
}, (reason)=>{
// 失敗時執行的回調
console.log('執行reject,輸出實例失敗態的reason屬性: ', reason);
throw new Error('失敗了');
}).then((value)=>{
// then的成功回調裏面輸出,前一個then成功回調的返回值(即promise實例的value屬性), 若是沒有顯示的return, 那麼返回的是undefined
console.log('第二個then的成功回調裏面輸出,前一個then成功回調的返回值: ',value); // 第二個then的成功回調裏面輸出,前一個then成功回調的返回值: 520
return value + 200;
}, (reason)=>{
console.log('第二個then的失敗: ', reason);
}).then((value)=>{
console.log('第三個then的成功回調裏面輸出,前一個then成功回調的返回值: ',value); // 第三個then的成功回調裏面輸出,前一個then成功回調的返回值: 720
});
// =>
2秒後執行resolve,輸出實例成功態的vlaue屬性: 420
第二個then的成功回調裏面輸出,前一個then成功回調的返回值: 520
第三個then的成功回調裏面輸出,前一個then成功回調的返回值: 720
複製代碼
function Promise(executor){
let self = this;
self.status = 'pending'; // pending => fulfilled | rejected
self.value = undefined;
self.reason = undefined;
self.onFulfilledCallbacks = []; // 用於存放全部then方法成功態的回調
self.onRejectedCallbacks = []; // 用於存放全部then方法失敗態的回調
// 成功
function resolve(value){
if(self.status === 'pending'){
self.value = value;
self.status = 'fulfilled';
self.onFulfilledCallbacks.forEach(fn=>fn());
}
}
function reject(reason){
if(self.status === 'pending'){
self.reason = reason;
self.status = 'rejected';
self.onRejectedCallbacks.forEach(fn=>fn());
}
}
try {
executor(resolve, reject); // 該函數會在new Promise()實例時當即調用,它接收兩個參數: resolve reject
}catch(err){
reject(err);
}
}
Promise.prototype.then = function(onFulfilled, onRejected){
let self = this;
let promise2 = new Promise(function(resolve, reject){
// console.log(this === self); // 這裏由於使用了箭頭函數,因此self === this, 指向同一個對象
// 該executor函數會裏面執行,所以把以前的狀態判斷及成功回調的代碼移到此處與以前功能同樣;
// 須要說明的是這個promise須要根據上一個的狀態和值進行判斷,故而設置self變量用於引用上一個this
if(self.status === 'fulfilled'){
let x = onFulfilled(self.value); // 成功回調; 若是沒有就當前對象的value屬性值
resolve(x); // 將處理後的結果做爲參數傳遞給promise實例的value屬性; 同時也會傳遞給下一個then的成功回調
}
if(self.status === 'rejected'){
try{
let x = onRejected(self.reason); // onRejected處理
reject(x);
}catch(e){
reject(e);
}
}
if(self.status === 'pending'){
self.onFulfilledCallbacks.push(()=>{
let x = onFulfilled(self.value);
resolve(x);
});
self.onRejectedCallbacks.push(()=>{
let x = onRejected(self.reason);
reject(x);
});
}
});
return promise2;
};
複製代碼
解析
採用鏈式的then,能夠指定一組按照次序調用的回調函數; 此時前一個回調函數,有可能返回的仍是一個Promise對象(即有異步操做),這時後一個回調函數,就會等待該Promise對象的狀態發生變化,纔會被調用;
所以處邏輯\代碼比較多,放在一塊兒看了
let p = new Promise((resolve, reject)=>{
resolve(1000);
// 或 resolve(new Promise((resolve, reject)=>{ resolve('成功');}))
});
p.then((value)=>{
return new Promise((resolve, reject)=>{
resolve(value + 500);
});
}).then((value)=>{
console.log(value); // 1500
});
複製代碼
function Promise(executor){
let self = this;
this.status = 'pending'; // pending => fulfilled | rejected
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = []; // 用於存放全部then方法成功態的回調
this.onRejectedCallbacks = []; // 用於存放全部then方法失敗態的回調
// 成功
function resolve(value){
// 若是value是個Promise實例, 就要先處理該promise實例
/*
let p = new Promise((resolve, reject)=>{
resolve(new Promise(function(resolve, reject){
resolve('成功');
}));
})
*/
if(value instanceof Promise){
return value.then((data)=>{
resolve(data);
},(y)=>{
reject(y);
});
}
if(self.status === 'pending'){
self.value = value;
self.status = 'fulfilled';
self.onFulfilledCallbacks.forEach(fn=>fn());
}
}
function reject(reason){
if(self.status === 'pending'){
self.reason = reason;
self.status = 'rejected';
self.onRejectedCallbacks.forEach(fn=>fn());
}
}
try {
executor(resolve, reject); // 該函數會在new Promise()實例時當即調用,它接收兩個參數: resolve reject
}catch(err){
reject(err);
}
}
function resolvePromise(x, promise2, resolve, reject){
// 若是then的回調函數中返回以前的promsie,就有問題了(由於狀態一旦改變就被凍結,不能再次變化))
if(x === promise2){
return reject(new TypeError('循環應用'));
}
// 判斷x是普通值仍是對象,若是是普通值,直接resolve
// 若是是對象或函數執行
if((x !== null && typeof x === 'object') || typeof x === 'function'){
// 這裏能夠是promise,而後嘗試執行
try {
// 判斷有沒有then方法, 在獲取then的過程當中也可能會出錯(好比某個對象的then屬性get的時候拋出錯誤)
/*
let obj = {};
Object.defineProperty(obj, 'then', {
get(){
throw new Error('不讓你get!');
}
});
*/
let then = x.then; // 獲取x的then屬性; 若是沒有就會拋出錯誤
if(typeof then === 'function'){
then.call(x, (y)=>{
// y有可能也是一個promise
// 遞歸解析,直到結果是普通值爲止
resolvePromise(y, promise2, resolve, reject);
}, (r)=>{
reject(r);
});
} else {
// 有多是普通對象或普通值 {then: 'xbs'}或{then: {}}
resolve(x);
}
}catch(e){
// 沒有then那可能就是一個普通對象{a:xxx}
reject(e);
}
} else {
resolve(x);
}
}
Promise.prototype.then = function(onFulfilled, onRejected){
// .then().then().then()值的穿透, 由於咱們在then沒傳回調參數時,手動給其添加了相應的回調函數
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value=> value;
onRejected = typeof onRejected === 'function' ? onRejected: err => {throw err};
let self = this;
let promise2 = new Promise(function(resolve, reject){
// 該executor函數會馬上執行,所以把以前的狀態判斷及成功回調的代碼移到此處與以前功能同樣;
// 須要說明的是這個promise須要根據上一個的狀態和值進行判斷,故而設置self變量用於引用上一個this
if(self.status === 'fulfilled'){
// 這裏要使用promise2, 因此須要增異步保證能夠獲取到promise2;
// 爲何要使用promise2? - 由於每次then要返回的是一個新的promise, 若是有人要返回上一個promise呢, 這時候就須要去判斷,promise2和x的關係
/*
// 看這裏就知道爲何要判斷x與promise2的關係了
let p = new Promise((resolve,reject)=>{
resolve('成功');
})
p.then((value)=>{
return p;
});
*/
// 使用定時器是爲了保障promise2能獲取到; (先執行同步代碼)異步代碼(setTimeout是宏任務,主棧代碼執行完畢,微任務執行後再執行)是在同步執行完成後執行,故而能夠獲取到promise2
setTimeout(function(){
// 爲何要try呢? 由於沒人能保證櫻花大道上沒有狗狗的翔
/*
let p = new Promise((resolve,reject)=>{
resolve('成功');
})
p.then((value)=>{
throw new Error('就欺負你怎麼了'); // 成功態中拋錯誤,可謂防不勝防啊
}, (reason)=>{
// 失敗回調...
})
*/
try {
let x = onFulfilled(self.value);
// 若是這次x是返回的新的promise如何處理?
// 採用統一的方法來處理x,判斷x是promise仍是普通值
resolvePromise(x, promise2, resolve, reject);
} catch(err) {
// 若是執行函數時拋出失敗 那麼會走向下一個then的失敗狀態
reject(err);
}
}, 0);
}
if(self.status === 'rejected'){
setTimeout(function(){
try {
let x = onRejected(self.reason); // onRejected處理
resolvePromise(x, promise2, resolve, reject);
} catch(err) {
// 若是執行函數時拋出失敗 那麼會走向下一個then的失敗狀態
reject(err);
}
}, 0)
}
if(self.status === 'pending'){
// 異步的處理在這裏
// 由於須要待異步執行完成後調用執行,而什麼時候調用並不知道; 所以要先存起來(訂閱),待狀態改變再執行(發佈)
self.onFulfilledCallbacks.push(()=>{
setTimeout(()=>{
// 一樣也會遇到成功態回調裏面拋出錯誤的狀況,因此也要try{}catch(){}一下
try{
let x = onFulfilled(self.value);
resolve(x);
}catch(err){
reject(err);
}
},0);
});
self.onRejectedCallbacks.push(()=>{
setTimeout(()=>{
// 一樣也會遇到成功態回調裏面拋出錯誤的狀況,因此也要try{}catch(){}一下
try{
let x = onRejected(self.reason);
reject(x);
}catch(err){
reject(err);
}
},0);
});
}
});
return promise2;
};
複製代碼
其實到這裏,Promise的核心已經實現了
Promise.prototype.catch方法是.then(null, rejection)或.then(undefined, rejection)的別名,用於指定發生錯誤時的回調函數
getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 處理 getJSON 和 前一個回調函數運行時發生的錯誤
console.log('發生錯誤!', error);
});
複製代碼
Promise.prototype.catch = function(errCallback){
return this.then(null, errCallback);
};
複製代碼
Promise.all方法用於將多個Promise實例,包裝成一個新的Promise實例
let p1 = new Promise((resolve, reject)=>{
resolve('p1-success!');
});
let p2 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('p2-success!');
}, 2000);
});
let p3 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('p3-success!');
}, 3000);
});
let p = Promise.all([p1, p2, p3]).then((result)=>{
console.log(result); // [ 'p1-success!', 'p2-success!', 'p3-success!' ]
});
複製代碼
Promise.all = function(values){
return new Promise(function(resolve, reject){
let results = []; // 存放結果
let index = 0; // 處理方法執行了幾回
function processData(resIndex, data){
index++;
results[resIndex] = data; // 將執行結束後的結果存放到結果數組(由於結果和執行順序有嚴格對應關係,因此不能用push,用arr[0] = value的形式);
if(index === values.length){
resolve(results); // 當結果數組和執行操做的數量同樣時,將結果返回
}
}
for(let i = 0; i < values.length; i++){
let current = values[i];
if(current && current.then && typeof current.then === 'function'){
// promise
current.then(y=>{
processData(i, y);
},reject)
} else {
processData(i, current); // 若是是普通值,直接返回
}
}
});
};
複製代碼
解析
let p1 = new Promise((resolve, reject)=>{
resolve('p1-success!');
});
let p2 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('p2-success!');
}, 2000);
});
let p3 = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('p3-success!');
}, 3000);
});
let p = Promise.race([p1, p2, p3]).then((result)=>{
console.log(result); //'p1-success!'
});
複製代碼
Promise.race = function(values){
return new Promise((resolve, reject)=>{
for(let i = 0; i < values.length; i++){
let current = values[i];
if(current && current.then && typeof current.then === 'function'){
current.then(resolve,reject);
} else {
resolve(current);
}
}
});
};
複製代碼
Promise.resolve 能夠將現有對象轉換爲Promise對象
let p = Promise.resolve(300);
console.log(p instanceof Promise); // true
複製代碼
Promise.resolve = function(value){
return new Promise(function(resolve,reject){
resolve(value);
});
};
複製代碼
Promise.reject 能夠將現有對象轉換爲Promise對象
let p = Promise.reject(300);
console.log(p instanceof Promise); // true
複製代碼
Promise.reject = function(reason){
return new Promise(function(resolve,reject){
reject(reason);
});
};
複製代碼
先告一段落啦, 因理解能力有限, 不免會有遺漏和誤差,若是您發現了請告知! 學習和成長的路上看了不少大佬的博客\視頻\文檔\代碼,一直在消費大佬的辛苦成果,本身寫一寫,算是向大佬致敬了!