class Promise{
constructor(excutor){
this.value = '';
this.reason = '';
this.status = 'padding'
this.onFulfilledCallback = []
this.onRejectedCallback = []
let resolve = (value)=>{
/*2.這個(gè)判斷是為了status不可逆 只能從 padding轉(zhuǎn)化為 成功或者失敗*/
if (this.status == 'padding') {
this.status = 'fulfilled'
this.value = value
/*3.當(dāng)轉(zhuǎn)態(tài)改變的時(shí)候依次執(zhí)行隊(duì)列里面儲存的then函數(shù)里面對應(yīng)的回調(diào)*/
this.onFulfilledCallback.forEach(fn=>{
fn()
})
}
};
let reject = (reason)=>{
/*2.這個(gè)判斷是為了status不可逆 只能從 padding轉(zhuǎn)化為 成功或者失敗*/
if (this.status == 'padding') {
this.status = 'rejected'
this.reason = reason
/*3.當(dāng)轉(zhuǎn)態(tài)改變的時(shí)候依次執(zhí)行隊(duì)列里面儲存的then函數(shù)里面對應(yīng)的回調(diào)*/
this.onRejectedCallback.forEach(fn=>{
fn()
})
}
};
/*1. 當(dāng)發(fā)生異常是捕獲異常 */
try{
excutor(resolve,reject)
}catch (e){
reject(e)
}
}
then(onFulfilled,onRejected){
//4.防止使用者不傳成功或失敗回調(diào)函數(shù),所以成功失敗回調(diào)都給了默認(rèn)回調(diào)函數(shù)
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
onRejected = typeof onRejected === "function" ? onRejected : error => { throw error };
let newPromise;
if(this.status == 'fulfilled'){
return newPromise = new Promise((resolve,reject)=>{
setTimeout(()=>{
try{
let x = onFulfilled(this.value)
this.resolvePromise(newPromise, x, resolve, reject);
}catch (e){
reject(e)
}
})
})
}
if(this.status == 'rejected'){
return newPromise = new Promise((resolve,reject)=>{
setTimeout(()=>{
try{
let x = onRejected(this.reason)
this.resolvePromise(newPromise, x, resolve, reject);
}catch (e){
reject(e)
}
})
})
}
if(this.status == 'padding'){
return newPromise = new Promise((resolve,reject)=> {
/*3.當(dāng)excutor為異步的時(shí)候先把then方法里面的回調(diào)儲存在失敗或者成功的隊(duì)列里面*/
// 一個(gè)promise可以then多次 ,等會改變狀態(tài)后會讓then中的函數(shù)執(zhí)行
// promise.then((data)=>{
// console.log('res',data);
// },(err)=>{
// console.log(err);
// });
// promise.then((data)=>{
// console.log('res',data);
//},(err)=>{
// console.log(err);
//});
this.onFulfilledCallback.push(() => {
//這里可以寫其他的代碼對resolve做一層封裝todo
setTimeout(()=> {
try {
let x = onFulfilled(this.value)
this.resolvePromise(newPromise, x, resolve, reject);
} catch (e) {
reject(e)
}
})
})
this.onRejectedCallback.push(() => {
setTimeout(()=> {
try {
let x = onRejected(this.reason)
this.resolvePromise(newPromise, x, resolve, reject);
} catch (e) {
reject(e)
}
})
})
})
}
//4.保證鏈?zhǔn)秸{(diào)用 返回this 這樣做雖然能鏈?zhǔn)秸{(diào)用但是 所有鏈?zhǔn)秸{(diào)用的回調(diào)函數(shù)都掛載到同一個(gè)對象上 且當(dāng)后面的then方法執(zhí)行
//的時(shí)候promise的狀態(tài)已經(jīng)確定會馬上執(zhí)行其對應(yīng)的回調(diào),并且參數(shù)都為this.value這一個(gè)值
//return this
}
catch(onRejected){
this.then(null,onRejected)
}
resolvePromise(newPromise,x,resolve,reject){
//2.3.1規(guī)范,避免循環(huán)引用
if (newPromise === x) {
return reject(new TypeError('Circular reference'));
}
//called變量主要是用來判斷如果resolvePromise函數(shù)已經(jīng)resolve或者reject了,那就不需要在執(zhí)行下面的resolce或者reject。
//設(shè)置一個(gè)標(biāo)志位,在執(zhí)行resolve或者reject其中之一后,講不能再執(zhí)行resolve或者reject eg:resolve();reject()
let called = false;
if (x != null && ((typeof x === 'object') || (typeof x === 'function'))) {
try{
let then = x.then;
if (typeof then === 'function') {
//2.3.3.3 如果 then 是一個(gè)函數(shù),以x為this調(diào)用then函數(shù),且第一個(gè)參數(shù)是resolve,第二個(gè)參數(shù)是reject
then.call(x, y => {
if (called) return;
called = true;
this.resolvePromise(newPromise, y, resolve, reject);
}, error => {
if (called) return;
called = true;
reject(error);
})
} else {
//2.3.3.4 如果 then不是一個(gè)函數(shù),則 以x為值fulfill promise。
resolve(x);
}
}catch(e){
if (called) return;
called = true;
reject(e);
}
}else {
resolve(x)
}
}
}
// 執(zhí)行測試用例需要用到的代碼
Promise.deferred = function() {
let defer = {};
defer.promise = new Promise((resolve, reject) => {
defer.resolve = resolve;
defer.reject = reject;
});
return defer;
}
try {
module.exports = Promise
} catch (e) {}
// 1.npm i -g promises-aplus-tests
// 2.promises-aplus-tests mypromise.js
手寫promise
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- Promise標(biāo)準(zhǔn)了解一下 傳送門1?? ??Promises/A+規(guī)范 傳送門2?? ??阮一峰前輩ECMAScri...
- 1. promise要解決的問題: 腦筋急轉(zhuǎn)彎:把牛關(guān)進(jìn)冰箱里,要分幾步? 很顯然,這三個(gè)操作不能顛倒順序,否則任...
- https://juejin.im/post/5b55c28ee51d45195a7139d6 擴(kuò)展 Promis...
- 一、Promise.all() 核心思路: Promise.myAll()返回的肯定是一個(gè)promise對象,所以...
- 1. Promise A+ 規(guī)范 官方英文地址:https://promisesaplus.com/ 中文翻譯可參...