Javascript Promise 多次返回.

Posted bywayboy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript Promise 多次返回.相关的知识,希望对你有一定的参考价值。

        在JS中 我们使用Promise 可以带来极大地方便。然而,一个Promise 只要 resolve 或者 reject一次后,后续的resolve 或者 reject调用都会被忽略。因为此时 Promise对象已经结束了 Pending 状态。

        然而,更多的时候,为了得到更好的用户使用体验,我们向服务器发送一个请求,并不急于等待服务器返回结果,而是在服务器真正完成这次请求之前,向用户展示更多的工作状态信息。 这在 http 请求中很少出现这种请求。但当使用WebSocket的时候。我们就迫切需要实现这种功能。

例如如下业务场景:

        我们在浏览器中使用条码枪扫描用户的付款码。 同时发起一笔交易。这个时候。服务器可能要做如下工作:

  1. 表单校验、检查产品库存。
  2. 向微信、支付宝发起交易请求。
  3. 创建订单
  4. 订单创建失败 则要发起退款,否则完成交易。

在实际场景中,步骤1一般是很快就能完成的,步骤 2 需要等待一些时间 步骤3和4也很快。

        步骤一期是不是必须,只不过是为了减少向微信发起不必要的交易请求而已。步骤3 则有失败的可能。因为创建订单的时候我们肯定是要检查锁定库存的,这个时候如果库存不足、或者过了可以交易时间则很可能交易失败。退款也会有一个过程。

在使用http协议请求的情况下,我们从提交数据到等待结果 刚好是一个resolve 或者 reject 在这过程中,我们只知道服务器在干活,并不知道具体细节。如果使用WebSocket 我们假定发起一笔交易后服务器有如下信息返回:

"success": true, "done":false, "message": “正在发起微信收款...”
"success": true, "done":false, "message": "用户正在付款..."
"success": true, "done":false, "message":"付款完成, 正在创建订单..."
"success": true, "done":true, "message": "交易成功!"

服务器总共返回了4条信息, success 代表是否是出错的信息, done 代表是否是最后一条消息。这个时候一个Promise 肯定无法满足要求。这个时候我们要对 Promise 做一个小小的扩展。收到 done=false的消息的时候,调用 update 更新信息,当收到最后一条消息的时候调用 resolve 或者reject 。实现代码如下:

/**
 * 
 * @param ((resolve: (value: any) => void, reject: (reason?: any) => void,, update: (reason?: any) => void) => void fn 
 * @returns PromiseEx
 */
function PromiseEx(fn)
    let _fn = [], _resolve, _reject, p;

    this.then = fn=>
        p.then(fn);
        return this;
    
    this.catch = fn=>
        p.catch(fn);
        return this;
    

    this.update = fn=>_fn.push(fn); return this;

    const update = (o)=>
        _fn.forEach(_cb=>_cb(o));
    

    p = new Promise((resolve, reject)=>
        fn(resolve, reject, update);
    )
    return this;


new PromiseEx((resolve, reject, update)=>
    let i = 0;
    let id = setInterval(() => 
        update(i++);
        if(i == 5)
            clearInterval(id);
            resolve(done:true)
        
    , 1000);
).then(res=>
    console.log('then', res)
).update(res=>
    console.log('update', res)
);

以上是关于Javascript Promise 多次返回.的主要内容,如果未能解决你的问题,请参考以下文章

Javascript Promise 多次返回.

Javascript Promise 多次返回.

Javascript等待Promise在返回响应之前完成for循环

promise

如何在做其他事情之前返回许多 Promise 并等待它们

使用promise,JavaScript时函数不返回值