原生Promise.resolve 和 Promise.reject
描述
- resolve具有等待效果
- reject不具有等待效果
Promise.resolve(new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('resolve')
},0)
})).then((v)=>{
console.log(v, 'resolve')
})
Promise.reject(new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('resolve',)
},0)
})).then(()=>{
},(err)=>{
console.log(err, 'reject');
})
运行结果分析
- Promise.reject中的Promise中的异步任务不起作用,hen会忽略 reject中的异步状态的变更。此时的then中失败的回调会捕获reject,但是此时的状态为pending。
- Promise.resolve中的异步任务会起作用,后面的then会等到Promise.resolve中Promsie状态的变化后再捕获
Promise { <pending> } reject
resolve onFulfilled
resolve和reject代码实现
const PENDING = 'pending';
const REJECTED = 'rejected';
const FULFILLED = 'fulfilled';
const resolvePromise = (promise2, x, resolve, reject) => {
if (promise2 === x) {
return reject(new TypeError('不能循环引用'));
}
if ((x !== null && typeof x === 'object') || typeof x === 'function') {
let called = false;
try {
let then = x.then;
if (typeof then === 'function') {
then.call(x,
(y) => {
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject)
},
(r) => {
if (called) return;
called = true;
reject(r)
},
)
} else {
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else {
resolve(x);
}
}
class Promise1 {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
// resolve具有等待效果
const resolve = (value) => {
// 处理,Promise.resolve参数为Promise
if (value instanceof Promise1) return value.then(resolve,reject);
if (this.status === FULFILLED) return;
// value未非promise的情况
this.value = value;
this.status = FULFILLED;
this.onFulfilledCallbacks.forEach(fn => fn());
}
const reject = (reason) => {
if (this.status === REJECTED) return;
this.reason = reason;
this.status = REJECTED;
this.onRejectedCallbacks.forEach(fn => fn())
}
try {
executor(resolve, reject);
} catch (e) {
reject(e)
}
}
then(onFulfilled, onRejected) {
const promise2 = new Promise1((resolve, reject) => {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected === 'function' ? onRejected : r => reject(r);
if (this.status === PENDING) {
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
if (this.status === FULFILLED) {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
if (this.status === REJECTED) {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
}
});
return promise2;
}
catch(fn){
return this.then(null,fn);
}
finally(cb) {
return this.then((v)=>{
//这里返回的仍然是上一个then返回的结果,cb中的返回值不影响下一个then的值
return Promise1.resolve(cb()).then(()=>v)
},(r)=>{
//一旦报错直接把错误向下传递
return Promise1.resolve(cb()).then(()=>{ throw r})
});
}
// resolve具有等待效果 次数的value可能是promise因此需要再resolve函数做处理
static resolve(value) {
return new Promise1((resolve, reject)=>{
resolve(value)
})
}
//没有等待效果 此处的reason可能是promise
static reject(reason) {
return new Promise1((resolve, reject) => {
reject(reason);
})
}
static all(array) {
}
static race(array) {
}
static any() {
}
static allSellted() {
}
}
// 以下是测试入口
Promise1.deferred = function() {
const dfd = {};
dfd.promise = new Promise1((resolve, reject)=>{
dfd.resolve = resolve;
dfd.reject = reject;
})
return dfd;
}
module.exports = Promise1;
测试代码如下
const Promise1 = require("./Promise1");
Promise1.resolve(new Promise1((resolve,reject)=>{
setTimeout(()=>{
resolve('resolve')
},0)
})).then((v)=>{
console.log(v, 'onFulfilled');
})
Promise1.reject(new Promise1((resolve,reject)=>{
setTimeout(()=>{
reject('resolve')
},0)
})).catch((err)=>{
console.log(err, 'catch')
})
运行结果分析
reject立即执行
resolve等到内部的promise解析完成后再执行
Promise1 {
status: 'rejected',
value: undefined,
reason: 'resolve',
onFulfilledCallbacks: [],
onRejectedCallbacks: []
} catch
resolve onFulfilled
finally 代码的实现
finally描述
- finally返回的也是then方法
- finally中的回调函数的返回值不会向下传递
- finally中如果又报错直接向下传递
- finally中的会回调函数都具有等待效果, 也就是说finnaly中的代码执行完毕后,后面的then或者catch才会执行。
代码实现
finally(cb) {
return this.then((v)=>{
//这里返回的仍然是上一个then返回的结果,cb中的返回值不影响下一个then的值
return Promise1.resolve(cb()).then(()=>v)
},(r)=>{
//一旦报错直接把错误向下传递
return Promise1.resolve(cb()).then(()=>{ throw r})
})
}
测试代码及结果分析
Promise1.resolve('1').finally(()=>{
return new Promise1((resolve, reject)=>{
setTimeout(()=>{
return resolve('xxx')
}, 300)
})
}).then((v)=>{
console.log(v,'value1');
}, r=>{
console.log(r, 'reason');
})
// 打印结果为1 value1
Promise1.reject('1').finally(()=>{
return new Promise1((resolve, reject)=>{
setTimeout(()=>{
return resolve('xxx'); //这里的状态不会影响到下一个then的值的传递
}, 300)
})
}).then((v)=>{
console.log(v,'value1');
}, r=>{
console.log(r, 'reason');
});
//打印结果: 1 reason
all 代码实现
- 传递是数组
- 数组中所有的都执行都是成功才是成功,有一个失败全部失败
- 数组中可能会存在多个异步多并发问题,次数需要用
计数器
和映射表
来保证并发问题
static all(methodsArray = []) {
// methodsArray可能存在多个异步,异步并发问题用计数器来处理
let index = 0;
const result = [];
function process(value,key,resolve,reject) {
result[key] = value;
try{
if(++index === methodsArray.length){
resolve(result)
}
}catch(e) {
reject(e)
}
}
return new Promise1((resolve,reject)=>{
methodsArray.forEach((promise,i)=>{
try {
if (typeof promise.then === 'function') {
promise.then((v)=>{
process(v,i,resolve, reject); //如果为Promise等到获取到结果后直接添加到映射数组result中
},reject);
}else {
process(promise, i, resolve, reject); //非promise可以直接把数据映射到数组result中
}
}catch(e) {
reject(e);
}
});
});
}
测试代码
const fs = require('fs');
const readFile = fs.promises.readFile;
const arr = [1,readFile('./2.txt', 'utf-8')];
Promise1.all(arr).then((v)=>{
console.log(v, 'all')
})
any 代码实现
- 参数为数组
- 有一个成功就是成功
这里方法的处理比all简单
// 有一个成功就成为 所有失败才为失败
static any(arrayOfMethods = []) {
let errorIndex = 0;
const errorResult = [];
// 保存失败的数据 全部失败就reject
function process(error, i,reject){
errorResult[i] = error;
if (errorIndex++ === arrayOfMethods.length) {
reject(errorResult);
}
}
return new Promise1((resolve, reject)=>{
//数组为空直接reject
if (!arrayOfMethods.length) return reject('没有可以迭代的数据');
try {
// 数组部位不为空的处理
arrayOfMethods.forEach((method, index)=>{
try {
if (typeof method.then === 'function') {
method.then(
(value)=>resolve(value),
(r)=>process(r, index, reject)
);
}else {
resolve(method);
}
}catch(e) {
process(e, index, reject);
}
});
}catch(e) {
reject(e); // 报错直接reject
}
});
}
race代码实现
- 传递数组
- race的结果始终采取最先改变的状态,fufilled或者rejected
// 最先失败就采用失败,最先成功就采用成功
static race(arrayOfMethods = []) {
return new Promise1((resolve,reject)=>{
if (!arrayOfMethods.length) return reject('not empty');
try {
arrayOfMethods.forEach((method, index)=>{
if (typeof method.then === 'function') {
method.then(v=>{
resolve(v)
return v
}, r=>{
reject(r);
});
} else {
resolve(method);
}
});
}catch(e) {
reject(e);
}
});
}