Promise之关键问题

1、如何改变 promise 的状态

resolve(value): 如果当前是pending就会变成 resolved

reject(reason): 如果当前是pending就会变成 rejected

抛出异常:如果当前是pending就会变为rejectd

🌰示例

<script>
    let p = new Promise((reosolve, reject) => {
        //1. resolve 函数
        reosolve('ok'); // pending => fulfilled (resolved)
        //2. reject 函数
        reject('error'); // pending => rejected
        //3. 抛出错误
        throw '出问题了'; // pending  => rejected
    })
    console.log(p); 
</script>

2、一个promise指定多个成功/失败回调函数,都会调用吗?

当前promise对象改变为对应状态时都会调用

🌰示例:pending => fulfilled (resolved)

⏰ pending => fulfilled (resolved)

<script>
    let p = new Promise((reosolve, reject) => {
        //1. resolve 函数
        reosolve('ok'); // pending => fulfilled (resolved)
    })

    p.then((value) => {
        console.log(value);
    })
    p.then((value) => {
        console.log(value)
    })
    p.then((value) => {
        console.log(value);
    })
</script>

结果:

⏰ pending => rejected

<script>
    let p = new Promise((reosolve, reject) => {
        //1. reject 函数
        reject('ok'); // pending => rejected
    })

    p.catch((value) => {
        console.log(value);
    })
    p.catch((value) => {
        console.log(value)
    })
    p.catch((value) => {
        console.log(value);
    })
</script>

结果

3、promise.then() 返回的新promise的结果由什么决定?

⏰ 简单表达式: 由then()指定的回调函数执行的结果决定

//1. 创建一个promise
let p = new Promise((reosolve, reject) => {
    reosolve('ok')
})

//2.执行then方法
let result = p.then((ref) => {
    console.log(ref)
}, (reason) => {
    console.log(reason);
})

先解决一个问题,p 和 result 是不是同一个promise? 我们验证一下

if (p === result) {
    console.log('执行then方法返回的还是旧promise')
} else {
    console.log('执行then方法产生了新的promise');
}

结果

我们可以得出结论promise.then() 返回了新promise。那么新promise 状态和值由谁确定呢?

  • 正常态
    <script>
        //1. 创建一个promise
        let p = new Promise((reosolve, reject) => {
            reosolve('ok')
        })
        console.log('p:', p)
        //2.执行then方法
        let result = p.then((ref) => {
            console.log(ref)
        }, (reason) => {
            console.log(reason);
        })
        console.log('result:', result)
    </script>

    结果

  • 失败态
    <script>
        //1. 创建一个promise
        let p = new Promise((reosolve, reject) => {
            reject('error')
        })
        console.log('p:', p)
        //2.执行then方法
        let result = p.then((ref) => {
            console.log(ref)
        }, (reason) => {
            console.log(reason);
        })
        console.log('result:', result)
    </script>

    结果

  • 抛出异常 
    <script>
        //1. 创建一个promise
        let p = new Promise((reosolve, reject) => {
            throw '异常了'
        })
        console.log('p:', p)
        //2.执行then方法
        let result = p.then((ref) => {
            console.log(ref)
        }, (reason) => {
            console.log(reason);
        })
        console.log('result:', result)
    </script>

    结果

❗️ 由此,我们可以得出结论,p 与 result 的状态和 存储值 之间没有任何关系。而是取决于then()指定的回调函数执行的结果。详细情况,看下面

⏰ 详细表达式: 

  • 如果抛出异常,新promise 变为rejected, reason 为抛出的异常

    <script>
        //1. 创建一个promise
        let p = new Promise((reosolve, reject) => {
            reosolve('ok')
        })
        console.log('p:', p)
    
        //2.执行then方法
        let result = p.then((ref) => {
            console.log(ref)
            //1.抛出错误
            throw '抛出异常'
        }, (reason) => {
            console.log(reason);
        })
        console.log('result:', result)
    </script>

    结果

  • 如果返回的是非promise的任意值, 新promise 变为 resolved, value为返回的值

    <script>
        //1. 创建一个promise
        let p = new Promise((reosolve, reject) => {
            reosolve('ok')
        })
        console.log('p:', p)
    
        //2.执行then方法
        let result = p.then((ref) => {
            console.log(ref)
            //1.抛出错误
            // throw '抛出异常'
            //2.返回结果是 非promise 类型的对象
            return 521
        }, (reason) => {
            console.log(reason);
        })
        console.log('result:', result)
    </script>

    结果

  • 如果返回的是另外一个新promise, 此promise 的结果就成为新promise的结果

    <script>
        //1. 创建一个promise
        let p = new Promise((reosolve, reject) => {
            reosolve('ok')
        })
        console.log('p:', p)
    
        //2.执行then方法
        let result = p.then((ref) => {
            console.log(ref)
            //1.抛出错误
            // throw '抛出异常'
            //2.返回结果是 非promise 类型的对象
            // return 521
            //3.返回结果是 一个promise 对象
            return Promise.resolve('Success')
        }, (reason) => {
            console.log(reason);
        })
        console.log('result:', result)
    </script>

    结果

4、promise 如何串联多个操作任务?

⏰ 1. promise 的 then() 返回一个新的promise, 可以开成then()的链式调用

<script>
    //1. 创建一个promise
    let p = new Promise((resolve, reject) => {
        setTimeout(()=> {
            resolve('ok')
        }, 1000)
    })
    //2.then的链式操作
    p.then((ref) => {
        return new Promise((resolve, reject) => {
            resolve('success')
        })
    }).then((value) => {
        console.log(value)
    })
</script>

结果

⏰ 2.通过then的链式调用串联多个同步/异步任务

  • 同步任务
    let p = new Promise((resolve,reject)=>{
        resolve('ok')
    }).then((reason)=>{
        console.log(111);
    }).then((reason)=>{
        console.log(222);
    }).then((reason)=>{
        console.log(333)
    }).then((reason)=>{
        console.log(444)
    })

    结果

    111
    222
    333
    444
  • 异步任务
    let p = new Promise((resolve, reject) => {
        resolve('ok')
    }).then((reason) => {
        console.log(111);
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('ok')
            }, 1000)
        })
    }).then((reason) => {
        console.log(222);
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('ok')
            }, 1000)
        })
    }).then((reason) => {
        console.log(333)
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('ok')
            }, 1000)
        })
    }).then((reason) => {
        console.log(444)
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('ok')
            }, 1000)
        })
    })

    结果

    111
    222
    333
    444

5、promise 异常透传?

⏰ 1. 当使用promise 的then链式调用时,可以在最后指定失败回调

let p = new Promise((resolve, reject) => {
    console.log(111)
    reject('err')
}).then((ref) => {
    console.log(222)
}).then((ref) => {
    console.log(222)
}).then((ref) => {
    console.log(222)
}).catch((reason) => {
    console.log(reason)
})

打印结果

111
err 

⏰ 2. 当前任何操作出了异常, 都会传到最后失败的问题中处理

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('ok')
    }, 1000)
}).then((ref) => {
    console.log(111)
}).then(() => {
    console.log(222)
    throw ('出错了2')
}).then(() => {
    console.log(333)
}).catch((err) => {
    console.log('catch', err);
})

打印结果:

111
222
catch 出错了2
⏰ 3. Promise 的 error 是如何在链式调用中向下传递的并被处理的呢?答案是: 隐式的 try…catch

通常,一遇到异常抛出,浏览器就会顺着 Promise 链寻找下一个就近的 onRejected 失败回调函数或者由 .catch() 指定的回调函数。你可以想象成 promise 的整个执行器(executor)和 promise 的处理程序周围有一个隐式的 “try...catch”。

这一错误的传递就被称为 promise 的异常穿透

let p = new Promise((resolve, reject) => {
    reject('失败了')
}).then((ref) => {
    console.log('onResolve', ref);
}, (err) => {
    console.log('onReject', err)
}).catch((err) => {
    console.log('catch', err);
})

结果

onReject 失败了

上述例子中,"失败了" 就会被离它最近的 then 中的 onRejected 函数所处理,而不会被 catch 所捕获。

6、中断promise链条?

当使用promise 的then链式调用时,在中间中断,不再调用后面的回调函数

⏰  办法:在回调函数中反应一个pendding状态的promise 对象。只有这一个办法!

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('ok')
    }, 1000)
}).then((ref) => {
    console.log(111)
}).then(() => {
    console.log(222)
    return new Promise(()=>{})
}).then(() => {
    console.log(333)
}).then(() => {
    console.log(444)
})

结果

111
222

posted on 2024-07-14 19:36  梁飞宇  阅读(11)  评论(0)    收藏  举报