Promise.reject(10010).then().then(function(value){
console.log('onFulfilled value: ',value);
}, function (reason) {
console.log('onRejected reason: ',reason)
})
複製代碼
Promise.resolve().then(function () {
var obj = {
name:'outer',
then:{name:'inner'},
}
return obj;
}).then(function(value){
console.log('onFulfilled value: ',value);
},function (reason) {
console.log('onRejected reason: ', reason)
})
複製代碼
Promise.resolve().then(function () {
var obj = {
then(resolvePromise,rejectPromise) {
resolvePromise(Promise.resolve(10010))
}
}
return obj;
}).then(function(value){
console.log('onFulfilled value: ',value);
},function (reason) {
console.log('onRejected reason: ', reason)
})
複製代碼
Promise.resolve().then(function () {
var obj = {
then(resolvePromise,rejectPromise) {
rejectPromise(Promise.resolve(10010))
}
}
return obj;
}).then(function(value){
console.log('onFulfilled value: ',value);
},function (reason) {
console.log('onRejected reason: ', reason)
})
複製代碼
var resolveAtGlobal;
var p = new Promise(function(resolve){
resolveAtGlobal = resolve;
});
p.then(function(value){
console.log('onFulfilled value: ', value);
},function(reason){
console.log('onRejected reason: ', reason);
});
resolveAtGlobal(p);
複製代碼
- 2.2.2 若是 onFulfilled 是一個函數
- 2.2.2.1 promise 是 fulfilled 狀態時它必須被調用,而且 promise 的 value 做爲它的第一個參數。
Promise.resolve().then(function(value){
console.log('onFulfilled value: ',value);
console.log(arguments.length)
console.log(arguments)
});
複製代碼
- 2.2.3 若是 onRejected 是一個函數
- 2.2.3.1 promise 是 rejected 狀態時它必須被調用,而且 promise 的 reason 做爲它的第一個參數。
Promise.reject().then(function(value){
console.log('onFulfilled value: ',value);
},function(){
console.log('onRejected');
console.log(arguments.length)
console.log(arguments)
});
複製代碼
- 2.2.5 onFulfilled 和 onRejected 必須以函數的形式被調用(即沒有this值)。[3.2]
Promise.resolve().then(function(){
console.log(this);
});
複製代碼
Promise.resolve().then(function(){
'use strict';
console.log(this);
})
複製代碼
- 2.2.7 then 必須返回一個promise [3.3]
- 2.2.7.1 若是 onFulfilled 或 onRejected 返回一個值 x,運行Promise決議程序 [[Resolve]](promise2, x)。
Promise.resolve(10010).then(function () {
return Promise.resolve(10086)
}).then(function(value){
console.log('onFulfilled value: ',value)// 10086
}, function (reason) {
console.log('onRejected reason: ',reason);
});
複製代碼
- 2.2.7.2 若是 onFulfilled 或 onRejected 拋出一個意外 e,promise2 必須以 e 爲 reason 被 rejected。
Promise.resolve().then(function () {
throw -1;
}).then(function(value){
console.log('onFulfilled value: ',value)
}, function (reason) {
console.log('onRejected reason: ',reason)// -1
})
複製代碼
Promise.reject().then(function(){},function () {
var a = null;
a.num = 1;
}).then(function(){}, function (reason) {
console.log('onRejected reason: ',reason) // TypeError
})
複製代碼
- 2.2.1.1 若是 onFulfilled 不是一個函數,它必須被忽略。
- 2.2.1.2 若是 onRejected 不是一個函數,它必須被忽略。
- 2.2.7.3 若是 onFulfilled 不是一個函數而且 promise1 處於 fulfilled 狀態,promise2 必須以與 promise1 一樣的 value轉變到 fulfilled 狀態。
- 2.2.7.4 若是 onRejected 不是一個函數而且 promise1 處於 rejected狀態,promise2 必須以與 promise1 一樣的 reason轉變到 rejected狀態。
Promise.reject(10010).then().then(function(){}, function (reason) {
console.log('onRejected reason: ',reason)// 10010
})
複製代碼
Promise.resolve(10086).then().then(function (value) {
console.log('onFulfilled value: ',value)// 10086
})
複製代碼
promise決議程序是一個抽象的操做,它把一個 promise 和一個 value 做爲輸入,咱們將這個表示爲 [[Resolve]](promise, x)。若是 x 是一個 thenable ,它將會試圖讓 promise 採用 x 的狀態,前提是x的行爲至少有點像一個 promise。不然,它將會用值 x 執行 promise。 對這些 thenable 的處理使得與 promise 實現方式可以去互相操做。只要它們公開了符合 Promise/A+ 的 then 方法。它還使得 promises/A+ 實現方式可以採用合理的 then 方法去「同化」不一致的實現方式。 爲了運行[[Resolve]](promise, x),執行如下步驟:算法
2.3.1 若是 promise 與 x 是同一個對象,以 Tyeperror 做爲 reason 去 reject promise。chrome
var resolveAtGlobal;
var p = new Promise(function(resolve){
resolveAtGlobal = resolve;
});
p.then(function(value){
console.log('onFulfilled value: ',value);
},function(reason){
console.log('onRejected reason: ', reason) // error:循環決議鏈
});
resolveAtGlobal(p);
複製代碼
var resolveAtGlobal;
var p = new Promise(function(resolve){
resolveAtGlobal = resolve;
}).then(function(value){
console.log('onFulfilled value: ',value);
return p;
},function(reason){
console.log('onRejected reason: ', reason) // error:循環決議鏈
});
p.then(function(value){
console.log('onFulfilled2 value: ',value);
},function(reason){
console.log('onRejected2 reason: ', reason) // error:循環決議鏈
});
resolveAtGlobal();
複製代碼
- 2.3.3 不然,若是 x 是一個對象或者函數:
- 2.3.3.1 讓 then 做爲 x.then。
- 2.3.3.2 若是取屬性 x.then 會致使拋出異常 e,則以 e 爲 reason reject promise。
var proxy = new Proxy({}, {
get: function (target, propKey, receiver) {
console.log(`getting ${propKey}!`);
throw -1;
},
});
Promise.resolve(1).then(function(){
return proxy;
}).then(function (value) {
console.log('onFulfilled value: ',value);
}, function (reason) {
console.log('onRejected reason: ', reason)
});
複製代碼
- 2.3.3.3 若是 then 是一個函數,讓 x 做爲 this 調用它,第一個參數爲 resolvePromise,第二個參數爲 rejectPromise,而後:
Promise.resolve().then(function () {
var obj = {
then() {
console.log('this === obj :', this === obj);
}
}
return obj;
});
複製代碼
- 2.3.3.3.1 若是使用value y 調用 resolvepromise 時,運行[[Resolve]](promise, y)。
Promise.resolve().then(function () {
var obj = {
then(resolvePromise,rejectPromise) {
resolvePromise(Promise.resolve(10010))
}
}
return obj;
}).then(function(value){
console.log('onFulfilled value: ',value); // 10010
})
複製代碼
- 2.3.3.3.2 若是使用reason r 調用 rejectPromise 時,也用 r reject promise。
Promise.resolve().then(function () {
var obj = {
then(resolvePromise,rejectPromise) {
rejectPromise(Promise.resolve(10010))
}
}
return obj;
}).then(function(value){
console.log('onFulfilled value: ',value);
},function (reason) {
console.log('onRejected reason: ', reason) // promise
})
複製代碼
- 2.3.3.3.3 若是 resolvePromise 和 rejectPromise 都被調用了,或屢次調用同一參數,那麼第一個調用優先,其餘的調用都會被忽略。
Promise.resolve().then(function () {
var obj = {
then(resolvePromise,rejectPromise) {
resolvePromise(10010);
rejectPromise(10000);
resolvePromise(10086);
}
}
return obj;
}).then(function(value){
console.log('onFulfilled value: ',value); // 10010
},function (reason) {
console.log('onRejected reason: ', reason)
})
複製代碼
- 2.3.3.3.4 若是調用 then 的過程當中拋出了一個意外 e,
- 2.3.3.3.4.1 若是 resolvePromise 或者 rejectPromise 被調用了,那麼忽略它。
- 2.3.3.3.4.2 不然,把 e 做爲 reason reject promise。
Promise.resolve().then(function () {
var obj = {
then(resolvePromise,rejectPromise) {
resolvePromise(10010);
throw -1
}
}
return obj;
}).then(function(value){
console.log('onFulfilled value: ',value); // 10010
},function (reason) {
console.log('onRejected reason: ', reason)
})
複製代碼
Promise.resolve().then(function () {
var obj = {
then(resolvePromise,rejectPromise) {
rejectPromise(10010);
throw -1
}
}
return obj;
}).then(function(value){
console.log('onFulfilled value: ',value);
},function (reason) {
console.log('onRejected reason: ', reason)// 10010
})
複製代碼
Promise.resolve().then(function () {
var obj = {
then(resolvePromise,rejectPromise) {
throw -1
}
}
return obj;
}).then(function(value){
console.log('onFulfilled value: ',value);
},function (reason) {
console.log('onRejected reason: ', reason)// -1
})
複製代碼
- 若是 then 不是一個函數,將 x 做爲參數執行 promise。
Promise.resolve().then(function () {
var obj = {
name:'outer',
then:{name:'inner'},
}
return obj;
}).then(function(value){
console.log('onFulfilled value: ',value); // value.name === 'outer'
},function (reason) {
console.log('onRejected reason: ', reason)
})
複製代碼
- 2.3.4 若是 x 不是一個對象或者函數,將 x 做爲參數執行 promise。
- 若是一個參與了 thenable 循環鏈的 thenable 去 resolve promise,這樣 [[Resolve]](promise, thenable) 的遞歸性質最終會致使 [[Resolve]](promise, thenable) 會被再次調用,遵循上述算法將會致使無限遞歸。咱們鼓勵去實現(但不是必需的)檢測這樣的遞歸,並以 TypeError 做爲 reason 去 reject Promise。[3.6]
// 使用chrome和火狐測試,並無實現遞歸檢測。瀏覽器當前標籤頁會失去響應, timeoutHandle也不會執行
Promise.resolve().then(function () {
var obj = {
then(resolvePromise, rejectPromise) {
resolvePromise(obj)
}
}
return obj;
}).then(function (value) {
console.log('onFulfilled value: ', value);
}, function (reason) {
console.log('onRejected reason: ', reason)
});
setTimeout(function timeoutHandle() {
console.log('timeout') // timer
}, 0);
複製代碼
- 3.注意
- 3.3 若是實現知足全部要求,則實現可能容許 promise2 == promise1。每一個實現都應該記錄它是否可以生成 promise2 == promise1 以及在什麼條件下。
- 3.6 實現方式中不該當在 thenbale 鏈中的深度設置主觀的限制,而且不該當假設鏈的深度超過主觀的限制後會是無限的。只有真正的循環才能致使 TypeError。若是遇到由無限多個不一樣 thenable 組成的鏈,那麼永遠遞歸是正確的行爲。
thenbale鏈
是否真正循環作出檢測呢。🤔Promise.resolve().then(function () {
var obj = {
then(resolvePromise, rejectPromise) {
if(Math.random()> 1e-10){
resolvePromise(obj)
}else{
resolvePromise('done');
}
}
}
return obj;
}).then(function (value) {
console.log('onFulfilled value: ', value);
}, function (reason) {
console.log('onRejected reason: ', reason)
});
setTimeout(function timeoutHandle() {
console.log('timeout') // timer
}, 0);
複製代碼
thenbale鏈
多是無限循環的,也可能不是,這是個機率問題😂.參考資料segmentfault