const PENDING = "PENDING";
const FULFILLED = "FULFILLED";
const REJECTED = "REJECTED";
// 决定then返回的promise的状态
function resolvePromise(x, promise2, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('循环引用'))
}
if (typeof x === 'object' && x !== null || typeof x === 'function') {
let called;
try {
let then = x.then; // 是promise,含有then方法
if (typeof then === 'function') {
// x是promise
// 需要使用call修改this指向x promise 避免再次从x上取值
then.call(x, (value) => {
// fulfilled
if (called) return;
called = true;
resolvePromise(value, promise2, resolve, reject)
}, (error) => {
// rejected
if (called) return;
called = true;
reject(error)
})
} else {
resolve(x)
}
} catch (e) {
if (called) return;
called = true;
reject(e)
}
} else {
// 普通值直接resolve 没有返回值,undefined也走这里
resolve(x)
}
}
class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolveCallbacks = []
this.onRejectCallbacks = []
const resolve = (value) => {
// 场景: resolve(promise)
if (value instanceof Promise) {
return value.then(resolve, reject)
}
if (this.status === PENDING) {
this.status = FULFILLED
this.value = value
this.onResolveCallbacks.forEach(fn => fn())
}
}
const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED
this.reason = reason
this.onRejectCallbacks.forEach(fn => fn())
}
}
try {
executor(resolve, reject)
} catch (error) {
reject(error)
}
}
then(onFulfilled, onRejected) {
// 场景:
// new Promise((resolve, reject) => {
// resolve(1)
// })
// .then().then((data) => {
// console.log(data)
// })
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function (data) {
return data
}
onRejected = typeof onRejected === 'function' ? onRejected : err => {
throw err
}
// then返回一个新的promise
let promise2 = new Promise((resolve, reject) => {
// 处理异步
if (this.status === PENDING) {
this.onResolveCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value)
resolvePromise(x, promise2, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
this.onRejectCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason)
resolvePromise(x, promise2, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
// 同步情况,直接处理,不需要放入队列
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)
}
})
}
})
return promise2
}
catch (errCallback) {
return this.then(null, errCallback)
}
static resolve(value) {
return new Promise((resolve) => {
resolve(value)
})
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
static all(promises) {
return new Promise((resolve, reject) => {
let times = 0;
const arr = []
function processMap(key, value) {
arr[key] = value;
if (++times === promises.length) {
resolve(arr)
}
}
for (let i = 0; i < promises.length; i++) {
let promise = promises[i]; // 可能是普通值,也可能是promise
let then = promise && promise.then
if (typeof then === 'function') {
then.call(promise, (data) => {
processMap(i, data)
}, reject)
} else {
processMap(i, promise)
}
}
})
}
// finally返回的promise的状态取决于调用它的promise的状态(xxx.finally())
finally(cb) {
return this.then((y) => {
return Promise.resolve(cb()).then(() => y, (err) => {
throw err
})
}, (err) => {
return Promise.resolve(cb()).then(() => {
throw err
})
})
}
static race(values) {
return new Promise((resolve, reject) => {
for (let i = 0; i < values.length; i++) {
let p = values[i]
// 原生的promise,如果里面放的是一个promise,会进行优化,不会再进行包装 1次then
// 自己写的promise,如果当前resolve里面放的是promise,会调用这个promise.then 2次then
Promise.resolve(p).then(resolve, reject)
}
})
}
}
Promise.deferred = function () {
let dfd = {}
dfd.promise = new Promise((resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject
})
return dfd
}
// deferred 延迟对象 目的是产生一个可以延迟的promise对象
function readFile(...args) {
let dfd = Promise.deferred();
fs.readFile(...args, function (err, data) {
if (err) return dfd.reject(err)
dfd.resolve(data)
})
return dfd.promise
}
module.exports = Promise
``
```js
async function a() {
console.log(1);
await b();
c();
}
async function b() {
console.log(2);
await '-';
console.log(3);
}
async function c() {
console.log(5);
}
a();
Promise.resolve().then(() => {
console.log(4);
});
// 1 2 3 4 5
promise模拟
于 2022-03-22 14:09:18 首次发布