const FULFILLED = "FULFILLED";
const REJECTED = "REJECTED";
// 所有的promise 都要遵循这个规范 这样就可以保证不同人写的promise可以混用
// 核心就在这个resolvePromise方法中
function resolvePromise(x, promise2, resolve, reject) {
// x 决定promise2 的状态 走成功还是失败
if (promise2 === x) {
return reject(new TypeError("循环引用"));
}
// 判断x 是不是一个promise 先保证x 得是一个对象或者函数,如果不是对象或者函数那么x 一定不是promise
if ((typeof x === "object" && x !== null) || typeof x === "function") {
let called;
// 我需要看 这个x 上有没有then方法 有then方法才说明他是一个promise
try {
let then = x.then; // x可能是别人写的promise 那么取then有风险,
if (typeof then === "function") {
then.call(x,(y) => {
// x.then((y)=>{},r=>{}) 取then就会有风险
if (called) return;
called = true;
resolvePromise(y, promise2, resolve, reject); // 递归解析直到我们的y的值是一个普通值
},
(r) => {
if (called) return;
called = true;
reject(r);
}
);
} else {
// 没有then方法的都执行这里
resolve(x); // 只是一个对象而已 就是一个普通值
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else {
// x 就是一个普通的值,直接把x 传递给promise2的成功即可
resolve(x);
}
}
class Promise {
constructor(executor) {
this.value = undefined;
this.reason = undefined;
this.status = PENDING;
this.onResvoledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
// 如何判断是不是一个promise 主要看有没有then方法
if (value instanceof Promise) {
return value.then(resolve, reject);
}
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
this.onResvoledCallbacks.forEach((fn) => fn());
}
};
const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach((fn) => fn());
}
};
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
then(onFulfilled, onRejected) {
// 有可能这个 onFulfilled, onRejected 是可选的
onFulfilled =
typeof onFulfilled === "function"
? onFulfilled
: function (data) {
return data;
};
onRejected =
typeof onRejected === "function"
? onRejected
: (err) => {
throw err;
};
let promise2 = new Promise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(x, promise2, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(x, promise2, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === PENDING) {
this.onResvoledCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(x, promise2, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(x, promise2, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
catch(errCallback) {
return this.then(null, errCallback);
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason);
});
}
static resolve(value) {
return new Promise((resolve, reject) => {
resolve(value);
});
}
static all(values) {
return new Promise((resolve, reject) => {
let times = 0;
function processMap(key, value) {
arr[key] = value;
if (++times === values.length) {
resolve(arr);
}
}
const arr = [];
for (let i = 0; i < values.length; i++) {
let val = values[i]; // 可能是promise 也有可能是普通值
let then = val && val.then;
if (typeof then === "function") {
then.call(
val,
(data) => {
// 获取成功的结果
processMap(i, data);
},
reject
);
} else {
processMap(i, val);
}
}
});
}
finally(cb) {
return this.then(
(y) => {
return Promise.resolve(cb()).then(() => y);
},
(r) => {
return Promise.resolve(cb()).then(() => {
throw r;
});
}
);
}
}
reject(new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('123')
})
}));
其实走到then的第二个回调函数中 , 然后拿到回调中的值其实是一个 Promise
resolve(new Promise((resolve, reject) => {
setTimeout(()=>{
resolve('123')
})
}));
这个在then的第1个回调函数中,拿到123
Promise.race = function (values) {
return new Promise((resolve, reject) => {
for (let i = 0; i < values.length; i++) {
let p = values[i];
Promise.resolve(p).then(resolve, reject);
}
});
};
Promise.race([
new Promise((resolve, reject) => {
reject(100);
}),
200,
])
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err, "catch");
});
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("ok");
}, 3000);
});
function withAbort(p) {
let abort = null;
let myErrorPromise = new Promise((resolve, reject) => {
abort = reject;
});
let returnPromise = Promise.race([p, myErrorPromise]);
returnPromise.abort = abort;
return returnPromise;
}
let promise2 = withAbort(p);
setTimeout(() => {
promise2.abort("超时");
}, 5000);
promise2
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err, "fail");
});
Promise.resolve().then(() => {
console.log('then1');
Promise.resolve().then(() => {
console.log('then1-1');
return Promise.resolve();
}).then(() => {
console.log('then1-2')
})
})
.then(() => {
console.log('then2');
return undefined
})
.then(() => {
console.log('then3');
})
.then(() => {
console.log('then4');
})
.then(() => {
console.log('then5');
})