Promise的常见方法和源码

Promise的常见方法和源码

Promise常见方法

Promise.reject(reason)

Promise.reject()方法返回一个带有拒绝原因的Promise对象。

Promise.reject(new Error("失败"))
    .catch(
        (err) => { console.log(err); }
    )

在这里插入图片描述

Promise.resolve(value)

Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。如果这个值是一个 promise ,那么将返回这个 promise ;如果这个值是thenable(即带有"then" 方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;否则返回的promise将以此值完成。
Promise.resolve方法会自动调用thenable对象中的then方法
注: 不要在解析为自身的thenable 上调用Promise.resolve。这将导致无限递归

//声明一个thenable对象
let thenable = {
    then: (resolve, reject) => {
        // resolve(thenable)//err:这样会无限递归
        resolve(100000)
    }
}

Promise.resolve(thenable)
    .then((res) => {
        console.log(res);//10000
    })

在这里插入图片描述

Promise.race(iterable)

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("one")
    }, 3000)
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("tow")
    }, 2000)
});

const promise3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("three")
    }, 1000)
});
Promise.race([promise1, promise2, promise3]).then((value) => {
    console.log(value); //three
});

在这里插入图片描述

Promise.all(iterable)

Promise.all()方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("tow")
    }, 1000)
});
const promise3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("three")
    }, 2000)
});
Promise.all([promise1, promise2, promise3]).then((values) => {
    console.log(values);//[3, 'tow', 'three']
});

该方法会等最后所有的promise完成时打印下面的结果
在这里插入图片描述

Promise.allSettled()

Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));

const promises = [promise1, promise2];

Promise.allSettled(promises)
    .then((results) => {
        console.log(results)
    });

在这里插入图片描述

Promise.any()

Promise.any()接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个消息为全部失败的 promise

const promise1 = Promise.reject(3);
const promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("tow")
    }, 1000)
});
const promise3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("three")
    }, 2000)
});
Promise.any([promise1, promise2, promise3]).then((values) => {
    console.log(values);//three
});

在这里插入图片描述

手写Promise源码


const PENDING = 'pending', //promise的三个状态
    FULFILLED = "fulfilled",
    REJECTED = "rejected"

class MyPromise {
    constructor(executor) {
        this.state = PENDING; // promise的状态
        this.value = undefined; // 存储成功的结果
        this.reason = undefined; // 存储失败的原因
        this.onResolvedCallback = []; //存储异步成功回调函数
        this.onRejectedCallback = []; // 储存异步失败回调函数

        const resolve = (value) => { //改变promise状态为成功的方法
            if (this.state === PENDING) {
                this.state = FULFILLED;
                this.value = value;
                this.onResolvedCallback.forEach(fn => fn()); //当状态到达成功时执行注册的异步函数
            }
        }

        const reject = (reason) => { //改变promise状态为失败的方法
            if (this.state === PENDING) {
                this.state = REJECTED;
                this.reason = reason;
                this.onRejectedCallback.forEach(fn => fn());
            }
        }

        try {
            executor(resolve, reject);
        } catch (error) { //捕获错误的信息
            reject(error);
        }

    }

    then(onFulFill, onRejected) {
        const p2 = new MyPromise((resolve, reject) => {
            let x;
            if (this.state === FULFILLED) {
                setTimeout(() => {
                    x = onFulFill(this.value)
                    resolvePromise(p2, x, resolve, reject);
                }, 0)
            }
            if (this.state === REJECTED) {
                x = onRejected(this.reason)
                resolvePromise(p2, x, resolve, reject);
            }
            if (this.state === PENDING) {
                this.onResolvedCallback.push(() => {
                    x = onFulFill(this.value);
                    resolvePromise(p2, x, resolve, reject);
                })
                this.onRejectedCallback.push(() => {
                    x = onRejected(this.reason);
                    resolvePromise(p2, x, resolve, reject);
                })
            }
        })
        return p2;
    }
}

function resolvePromise(p2, x, resolve, reject) {
    if (p2 === x) {
        return new Error("引用错误");
    }
    // 判断是否thenable对象或者函数
    if (typeof x === "object" && x !== null || typeof x === "function") {
        try {
            let then = x.then;
            if (typeof then === "function") {
                then.call(
                    x,
                    y => {
                        resolvePromise(p2, y, resolve, reject)
                    },
                    err => reject(err))
            }
        } catch (error) {
            reject(error)
        }
    } else {
        resolve(x);
    }
}

测试代码

const p1 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve(100)
    }, 1000)
})

p1.then(
    (res) => {
        // 第一种 thenable对象
        // return {
        //     then(resolve, reject) {
        //         reject(10000)
        //     }
        // }
        // 第二种 Promise对象
        return new MyPromise((resolve, reject) => {
            resolve(
                new MyPromise((resolve, reject) => {
                    resolve(1000)
                })
            )
        })
    },
    (err) => {
        console.log(err);
    })
    .then(
        (result) => {
            console.log(result);
        },
        (err) => {
            console.log(err);
        })

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值