promise

promise 定义

Promise:promise 是⼀个拥有 then ⽅法的对象或函数,其⾏为符合本规范。 具有 then ⽅法(thenable):是⼀个定义了 then ⽅法的对象或函数; 值(value):指任何 JavaScript 的合法值(包括 undefined , thenable 和 promise); 异常(exception):是使⽤ throw 语句抛出的⼀个值。 原因(reason):表示⼀个 promise 的拒绝原因

.如果onFulfilled是一个函数,且有返回值,则返回值可以继续传递给后续的then
.如果onFulfilled是一个函数,但没有返回值(相当于return undefined),则后续then中的入参为undefined
.如果onFulfilled不是函数,则忽略当前then,将参数直接传递给后续的then
如果 x 有 then ⽅法且看上去像⼀个 Promise ,解决程序即尝试使 promise 接受 x 的状态;否则其 ⽤ x 的值来执⾏ promise 。 如果 promise 和 x 指向同⼀对象,以 TypeError 为据因拒绝执⾏ promise 如果 x 为 promise 如果 x 处于等待态, promise 需保持为等待态直⾄ x 被执⾏或拒绝 如果 x 处于执⾏态,⽤相同的值执⾏ promise 如果 x 处于拒绝态,⽤相同的据因拒绝 promise
.如果 x 为 Object 或 function(不常⻅) ⾸先尝试执⾏ x.then 如果取 x.then 的值时抛出错误 e ,则以 e 为据因拒绝 promise 如果 then 是函数,将 x 作为函数的作⽤域 this 调⽤。传递两个回调函数作为参数,第⼀ 个参数叫做 resolvePromise ,第⼆个参数叫做 rejectPromise : 如果 resolvePromise 以值 y 为参数被调⽤,则运⾏ [[Resolve]](promise, y) 如果 rejectPromise 以据因 r 为参数被调⽤,则以据因 r 拒绝 promise promise.then(function(x) { console.log('会执⾏这个函数,同时传⼊ x 变量的值', x); });
.如果 resolvePromise 和 rejectPromise 均被调⽤,或者被同⼀参数调⽤了多次,则优先 采⽤⾸次调⽤并忽略其他的调⽤ 如果调⽤ then ⽅法抛出了异常 e 如果 resolvePromise 或 rejectPromise 已经被调⽤,则忽略 否则以 e 为据因拒绝 promise 如果 then 不为函数,以 x 为参数将 promise 变为已完成状态 如果 x 不为对象或者函数,以 x 为参数将 promise 变为已完成状态(重要且常⻅)

promise 解决过程

Promise 解决过程是⼀个抽象的操作,其需输⼊⼀个 promise 和⼀个值,我们表示为 [[Resolve]] (promise, x) (这句话的意思就是把 promise resolve 了,同时传⼊ x 作为值)
如果 x 有 then ⽅法且看上去像⼀个 Promise ,解决程序即尝试使 promise 接受 x 的状态;否则其 ⽤ x 的值来执⾏ promise 。
如果 promise 和 x 指向同⼀对象,以 TypeError 为据因拒绝执⾏ promise
如果 x 为 promise
如果 x 处于等待态, promise 需保持为等待态直⾄ x 被执⾏或拒绝
如果 x 处于执⾏态,⽤相同的值执⾏ promise
如果 x 处于拒绝态,⽤相同的据因拒绝 promise

容易忽略的两个点

1、promise异步执行是在 .then后.then前还是同步执行
2、如果没有return,promise会成为一个副作用,然后把undefined传递给后续的then, then并不会等待这个promise!

两个例题 例题1

 

scss

代码解读

复制代码

const log = console.log new Promise((res, rej) => { log(1) res() }) .then(()=>{ log(2) return new Promise((res, rej)=>{ log(3) res() }) .then(()=>{log(4)}) .then(()=>{log(5)}) }) .then(() => {log(6)})

// 1 2 3 4 5 6 例题2

 

scss

代码解读

复制代码

const log = console.log new Promise((res, rej) => { log(1) res() }) .then(() => { log(2) new Promise((res, rej)=>{ log(3) res() }) .then(()=>{log(4)}) .then(()=>{log(5)}) }) .then(() => { log(6) })

// 1 2 3 4 6 5 这两段代码的区别在于对Promise对象的使用方式和then方法的调用时机不同。

第一段代码使用了链式调用,即在第一个Promise的then方法中返回了一个undefined,然后继续调用后续的then方法。在第一个Promise的resolve方法被调用之后,会执行第一个then方法的回调函数,即打印2,然后创建一个新的Promise对象,并在其then方法中连续调用了两个then方法,分别打印4和5。最后,执行第一个Promise的then方法的回调函数,即打印6。

第二段代码执行顺序 123645 进入第一个promise第一个then(微任务队列1)后进入第二个promise,第二个.then进入微任务队列,第二个promise没有retrun是同步执行,第二个promise执行成功后立即执行4,子promise第二个then微任务队列(微任务队列3)挂起。至此第一个.then微任务任务执行完成,执行第二个微任务队(微任务队列2)列 log(6),微任务先进先出原则 先执行微任务队列2 再执行微任务队列3

因此,两段代码的区别在于第一个Promise对象的then方法的返回值不同(一个返回undefined,一个返回一个新的Promise对象),以及第一个Promise对象的then方法的调用时机不同(第一个代码是在第一个Promise的回调函数中调用的,第二个代码是直接在Promise对象上调用的)

promise 手搓源码

class CustomPromise {
    constructor(handleFunc) {
        this.status = 'pending'
        this.value = undefined
        this.fulfilledList = []
        this.rejectedList = []

        handleFunc(this.triggerResolve.bind(this), this.triggerReject.bind(this))
    }
    triggerResolve(val) {
        // 把当前的promise状态已经变成了 resolve,要执行后续的操作
        setTimeout(()=>{
            if (this.status !== 'pending') return
            // 传入的值是一个promise
            if (val instanceof CustomPromise) {
                val.then(
                    value => {},
                    err => {}
                )
            }else {
                // resolve方法传入的是普通值
                this.status = 'fulfilled'
                this.value = val
                // 执行已完成
                this.triggerFulfilled(val)
            }
        },0)
    }
    triggerFulfilled(val) {
        this.fulfilledList.forEach(item => item(val))
        this.fulfilledList = []
    }

    triggerReject() {

    }
    then(onFulfilled,onRejected){
        const {value,status} = this
        // then ⽅法必须返回⼀个 promise 对象 promise2 = promise1.then(onFulfilled, onRejected)
        const promiseInstance = new CustomPromise((onNextFulfilled, onNextRejected) => {

            function onFinalFulfilled(val) {
                // 如果 onFulfilled 不是函数且 promise1 状态变为已完成, promise2 必须成功执⾏并返回相同的值
                if (typeof onFulfilled !== 'function') { // 如果then里面注册的不是函数把上一个promise返回结果放到下一个promise执行
                    onNextFulfilled(val)
                }else {
                  /*如果 onFulfilled 是⼀个函数*/
                    // 判断上一步函数的执行结果的值
                    const res = onFulfilled(val)
                    // 如果 promise 和 x 指向同⼀对象,以 TypeError 为据因拒绝执⾏ promise
                    if (res === promiseInstance){
                        throw Error('两次是promises实例相等')
                    }
                    // 上一步结果是 Promise 执行 Promise.then
                    if (res instanceof CustomPromise) {
                        res.then(onNextFulfilled, onNextRejected)
                    // 不是Promise 直接返回上次函数返回的值
                    }else {
                        onNextFulfilled(res)
                    }
                }
            }
            function onFinalRejected(error) {
                if (typeof onRejected != 'function'){
                    onNextRejected(error)
                }else {
                    let res = null
                    try {
                        const res = onRejected(error)
                    } catch (e){
                        onNextRejected(e)
                    }
                    if (res instanceof  CustomPromise){
                        res.catch(onNextFulfilled, onNextRejected)
                    }else {
                        onNextRejected(res)
                    }
                }
            }
            switch (status) {
                case 'pending': {
                    this.fulfilledList.push(onFinalFulfilled)
                    this.rejectedList.push(onFinalRejected)
                    break
                }
                case 'fulfilled': {
                    onFinalFulfilled(value)
                    break
                }
            }
        })
        return promiseInstance
    }
    catch(){

    }
    static resolve(value) {
        // 是promise直接返回promise
        if (value instanceof CustomPromise) return value
        // 不是promise返回对应函数或者值
        return new CustomPromise(resolve => resolve(value))
    }
    static reject() {

    }
    static all(list) {
        return new CustomPromise((resolve,reject) => {
            // 异步执行成功数量
            let count = 0
            const values = []
            // 循环解构循环 例 [0,promise(1000)] [1,promise(2000)]
            for (const [i, promiseInstance] of list.entries()) {
                // 避免参数不是promise再调用下 promise.resolve()方法
                CustomPromise.resolve(promiseInstance)
                    .then(
                        res => {
                            values[i] = res
                            // 有一次resolve成功数目加1
                            count ++
                            // 总次数和all参数一致时返回总成功回调
                            if (count === list.length) resolve(values)
                        },
                        err => {
                            reject(err)
                        }
                        )
            }
        })
    }
    static race(list) {
        return new CustomPromise((resolve,reject) => {
            list.forEach(item => {
                CustomPromise.resolve(item)
                    .then(
                        res => {
                            resolve(res)
                        },
                        err => {
                            reject(err)
                        }
                    )
            })
        })
    }
}

const promise = function(time) {
    return new CustomPromise(function(resolve, reject) {
        return setTimeout(resolve, time)
    })
}

const promiseInstance = promise(0)
setTimeout(function() {
    promiseInstance.then(function() {console.log('hello world')})
}, 3000)

// .then(function(str) {console.log(str); return str;})
// .then(function(str2) {console.log('resolve2', str2)})

// CustomPromise.all([promise(1000), promise(3000), 'hello world'])
//     .then(function() {
//         console.log('all CustomPromise resolevd')
//     })

promise 为什么可以链式调用因为返回的是一个promise

async awit  是promise 和Generator的语法糖

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值