Promise其他方法的实现

4 篇文章 0 订阅

原生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);
            }
        });
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 Promise 的其他方法实现代码: 1. Promise.all:用于处理多个异步操作,等待所有操作完成后返回结果。 ```javascript const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('操作1成功'); }, 1000); }); const promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('操作2成功'); }, 2000); }); Promise.all([promise1, promise2]) .then((results) => { console.log('所有操作成功:', results); }) .catch((error) => { console.log('操作失败:', error); }); ``` 2. Promise.race:用于处理多个异步操作,返回最先完成的操作结果。 ```javascript const promise1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('操作1成功'); }, 1000); }); const promise2 = new Promise((resolve, reject) => { setTimeout(() => { resolve('操作2成功'); }, 2000); }); Promise.race([promise1, promise2]) .then((result) => { console.log('最先完成的操作成功:', result); }) .catch((error) => { console.log('操作失败:', error); }); ``` 3. Promise.resolve:用于将一个值或者一个 Promise 对象转换为一个已完成状态的 Promise 对象。 ```javascript const value = '操作成功'; Promise.resolve(value) .then((result) => { console.log('操作成功:', result); }) .catch((error) => { console.log('操作失败:', error); }); ``` 4. Promise.reject:用于将一个错误信息转换为一个已拒绝状态的 Promise 对象。 ```javascript const error = '操作失败'; Promise.reject(error) .then((result) => { console.log('操作成功:', result); }) .catch((error) => { console.log('操作失败:', error); }); ``` 希望以上代码能帮助您更好地理解 Promise 的其他方法。如果还有任何疑问,请随时追问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值