异步处理——Promise

Promise

用于表示一个异步操作的最终完成 (或失败)及其结果值。

状态

function test(resolve, reject) {
    var timeOut = Math.random() * 2;
    console.log('pending...')
    setTimeout(function () {
        if (timeOut < 1) {
            // fulfilled
            console.log('call resolve()...');
            resolve('200 OK');
        }
        else {
            // rejected
            console.log('call reject()...');
            reject('400 error');
        }
    }, 0);
}

  • 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。

    var pending = new Promise(test); // pending...
    
  • 已兑现(fulfilled): 意味着操作成功完成。

    pending.then((res)=>{console.log(res)}); // 200 OK
    
  • 已拒绝(rejected): 意味着操作失败。

    pending.catch((res)=>{console.log(res)}); // 400 error
    

事实上我们在.then()函数里面,如果抛出错误也会进入.catch()函数里面,这是因为Promise.prototype.thenPromise.prototype.catch方法返回的是Promise对象。

pending.then((res)=>{throw 'error'}); // 会进入pending.catch()里面

.catch()也抛出错误那么就会触发unhandledrejection事件(在下面有所介绍)。

pending.catch((res)=>{throw 'error'})

有一点你需要注意因为JavaScript是单线程,所以.then().catch()会在当前作用域执行完后执行。

pending
    .then(function (res) {console.log(res)})
    .catch(function (res) {console.log(res)});
console.log('start...');

监听拒绝(reject)事件

当 Promise 被拒绝时,会触发rejectionhandledunhandledrejection事件并被派发到全局作用域。

  • rejectionhandled

    当 Promise 被拒绝、并且在 reject 函数处理该 rejection 之后会派发此事件。

  • unhandledrejection

    当 Promise 被拒绝,但没有提供 reject 函数来处理该 rejection 时,会派发此事件。

通过window.addEventListener监听Promise拒绝事件。这个事件有两个属性,一个是promise属性,该属性指向被驳回的Promise;另一个是reason属性,该属性用来说明Promise被驳回的原因。

window.addEventListener("unhandledrejection", (event)=>{
    console.log(event.promise, event.reason, event);
})

链式调用

连续执行两个或者多个异步操作是一个常见的需求,在上一个操作执行成功之后,开始下一个的操作,并带着上一步操作所返回的结果。我们可以通过创造一个Promise链来实现这种需求。

[func1, func2, func3].reduce((p, f) => p.then(f), Promise.resolve())

await

用于等待一个Promise对象。

只能在异步函数(async function)中使用。

  • 若Promise正常处理(fulfilled),其回调的resolve函数参数作为await表达式的值,继续执行async function

  • 若Promise处理异常(rejected),await 表达式会把Promise的异常原因抛出。

  • 若await操作符后的表达式的值不是一个Promise,则返回该值本身。

(async function () {
    function test(resolve, reject) {
        var timeOut = Math.random() * 2;
        console.log('pending...')
        setTimeout(function () {
            if (timeOut < 1) {
                // fulfilled
                console.log('call resolve()...');
                resolve('200 OK');
            }
            else {
                // rejected
                console.log('call reject()...');
                reject('400 error');
            }
        }, 0);
    }
    window.addEventListener("unhandledrejection", event => {
        console.log('unhandledrejection', event.promise, event.reason, event);
    })
    var pending = await new Promise(test)
        .then(function (res) { console.log(res) })
        .catch(function (res) { console.log(res) });
    // 等待pending运行完 在运行下面代码
    console.log('start...');
})()

Promise - JavaScript | MDN (mozilla.org)

await - JavaScript | MDN (mozilla.org)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hjhcos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值