ECMAScript Promise 中的进度通知

Posted

技术标签:

【中文标题】ECMAScript Promise 中的进度通知【英文标题】:progress notifications in ECMAScript Promise 【发布时间】:2015-12-30 19:30:47 【问题描述】:

我们正在使用ECMAScript 6 promises

我们需要向最终用户实施进度通知(这是纯粹的 UX 要求)。我知道其他承诺框架(例如Q promise 库)允许这样做。

我们如何才能最优雅地采用某种进度指示?

或者我们应该迁移到不同的框架? (我不知道如何估计后者的努力)

【问题讨论】:

2018 年 - 使用异步生成器 你想把它放在答案中吗,@benjamin? @Shog9 我知道,但我不确定如何诚实,因为与实际核心问题(多个进度事件或流式传输)相比,前提(将 Q 承诺转换为进度通知)不是很好) - 一旦我弄清楚了,我可能会制作一个新的规范 【参考方案1】:

由于只有特定的 Promise 实例会产生进度,我们可以按需对其进行修补,如下所示:

   function reparse()
        let notify
        let promise = new Promise(async(resolve,reject)=>
            instanceOfjQueryDeferred.done(()=>
                resolve(100)
            ).progress((progress)=>
                notify(progress)
            )
        )
        // here is the monkey patch
        promise.progress  = (handler)=>
            notify = handler
            return promise
        
        return promise
    

并像这样使用它:

reparse().progress((p)=>
    console.log('progress',p)
).then((progress)=>
    console.log('done',progress)
)

【讨论】:

【参考方案2】:

ES2015 承诺永远不会有进展。 Promise 代表一个奇异的最终值。如果你想要多个值,你可以查看 observables - 或者将进度放在 promise 返回函数上。

将进度放在 Promise 返回函数上非常容易。基本上,您将回调作为函数的参数,并在应该发生进度通知时调用它。

以下是改编自我们的指南bluebird 的一些文字:

Progression 与使用 Promise Progression 处理程序的 API 存在可组合性和链接问题。随着其他库远离progress API,因为它与promise几乎没有关系,Bluebird也将如此。可以使用类似于 C# 中的IProgress 的模式来实现进度条的常见用例。

以前用过jQuery:

Promise.resolve($.get(...))
    .progressed(function() 
        // ...
    )
    .then(function() 
        // ...
    )
    .catch(function(e) 
        // ...
    )

使用 jQuery 之后:

Promise.resolve($.get(...).progress(function() 
        // ...
    ))
    .then(function() 
        // ...
    )
    .catch(function(e) 
        // ...
    )

在 C# 中实现通用进度接口:

function returnsPromiseWithProgress(progressHandler) 
    return doFirstAction().tap(function() 
        progressHandler(0.33);
    ).then(doSecondAction).tap(function() 
        progressHandler(0.66);
    ).then(doThirdAction).tap(function() 
        progressHandler(1.00);
    );


returnsPromiseWithProgress(function(progress) 
    ui.progressbar.setWidth((progress * 200) + "px"); // update with on client side
).then(function(value)  // action complete
   // entire chain is complete.
).catch(function(e) 
    // error
);

【讨论】:

以上是关于ECMAScript Promise 中的进度通知的主要内容,如果未能解决你的问题,请参考以下文章

ECMAScript 6 Promise 对象

Promise in ECMAScript | 前端技术探索

本地通知中的进度视图

[转]JS - Promise使用详解2(ES6中的Promise)

Promise.map() 进度指示器

如何在service中同步更新通知activity中的进度条