【问题标题】:How to get XMLHttpRequest Promise progress如何获取 XMLHttpRequest Promise 进度
【发布时间】:2016-08-12 17:04:21
【问题描述】:

我正在使用 JS Promise 重构我们的 JS API。但是我遇到了一个问题,阻止了我更进一步。

基本上,我们的 API 之一是发出异步 GET 请求并下载大文件。

所以API的用法是这样的:

var callback = {
  success: function(data){...},
  failure: function(data){...}
}    

Test(token).download(url).then(callback.success, callback.failure);

Test 函数向 url 发出 XHR 请求并调用 onload 和 onerror 事件处理程序中的回调函数。

问题是在下载过程中,需要刷新UI,即进度条,在onprogress中处理。

callback.success 只会在 Promise 被解析时被调用一次。那么我应该如何实现应该在Test函数内部XHR组件的onprogress事件处理程序中调用的UI刷新回调呢?

【问题讨论】:

  • 创建多个独立的 Promise。
  • @zerkms 但我只想发出一个下载请求并下载一个文件。

标签: javascript ajax xmlhttprequest promise


【解决方案1】:

由于 JavaScript 中的 Promise 只是状态机,因此无法获取 Promise 的进度。您将不得不使用其他方式。

参见这篇文章例如:progress notifications in ECMAScript Promise

【讨论】:

    【解决方案2】:

    Promises 根本不是多个进度通知的良好架构匹配。 Promise 是一种单向状态机,旨在传达完成或错误 - 这就是它们的全部设计目的。它们没有内置任何用于执行多个进度通知的机制。

    相反,对于进度通知,您应该使用其他架构机制,例如每次调用的常规回调或触发多个进度事件的eventEmitter。

    在您目前展示的方案中,它可能看起来像这样:

    var callback = {
      success: function(data){...},
      failure: function(data){...},
      progress: function(data){...}
    }    
    
    Test(token).download(url, callback.progress).then(callback.success, callback.failure);
    

    然后,在您的 download() 函数中,您可以根据需要多次调用进度回调。


    就个人而言,我认为如果您只返回承诺并让他们自己提供解决和拒绝处理程序而不是隐藏承诺并让您的呼叫者使用 2013 年回调架构,那么对您的呼叫者来说会更有用。返回 Promise 允许他们使用所有的 Promise 功能,例如链接、与其他 Promise 的聚合、在他们自己的代码中传播错误等等......

    因此,与其传入带有多个回调的callback 对象,它们传入的只是进度回调,然后您返回一个承诺。然后,调用者可以在返回的 Promise 上附加他们自己的解析和拒绝处理程序。现在是 2016 年,承诺在 ES6 中标准化。无需向调用者隐藏它们,并且完全有理由返回承诺,以便调用者也可以利用承诺的好处。

    【讨论】:

    • 其实我在developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…上使用 XMLHttpRequest Promise 示例
    • @deepsky - 好吧,我不同意这个例子的工作原理。在这些承诺标准化的时代,您不妨将承诺返回给您的调用者,让他们享受使用承诺的好处。通过不让调用者使用返回的承诺,您将减少 80% 的使用承诺的好处。
    猜你喜欢
    • 2010-09-09
    • 2017-01-21
    • 2011-04-28
    • 2011-11-16
    • 1970-01-01
    • 2018-01-23
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    相关资源
    最近更新 更多