2

进度处理程序已在一些领先的 ​​Promise 库(QWhenBluebird)中被弃用,并且也已从新的Promises/A+ 规范中删除。虽然我理解取消进度事件背后的原因,但我在重构以下我已经非常习惯的模式时遇到了麻烦:

var download = function(url) {
  var deferred = Q.defer();
  ...
  http.get(url, function(res) {
    res.on('data', function(chunk) {
      data += chunk.toString();
      deferred.notify('Downloading: ' + (data.length / totalLength) + '%'); 
      /* ^Notify download progress, but progress events are now deprecated :( */
    });
    res.on('end', function() {
      deferred.resolve('Success: ' + url);
    });
    res.on('error', function(err) {
      deferred.reject(err);
    });
  });
  return deferred.promise;
}
...
download(url).then(console.log, console.log, console.log); 
/* ^The third handler keeps logging progress, but this is now deprecated :( */

我已经看到网络上到处出现代码重构示例,但在所有这些示例中,进度更新的数量似乎是事先知道的。在上述模式中,可能发布的进度更新数量是不确定的。

有人可以在不使用进度事件/处理程序的情况下帮助我实现上述模式吗?

4

1 回答 1

1

进步的问题在于它与承诺是正交的并且没有很好地组合。你这样做的方式是从功能。

我这样做的方式(你也可以在 Bluebird API 文档中阅读)是这样的:

var download = function(url, newData) {
  var deferred = Q.defer();
  ...
  http.get(url, function(res) {
    res.on('data', function(chunk) {
      data += chunk.toString();
      if(typeof newData === "function") newData(data);
    });
    res.on('end', function() {
      deferred.resolve('Success: ' + url);
    });
    res.on('error', function(err) {
      deferred.reject(err);
    });
  });
  return deferred.promise;
}
...
download(url, logOnNewData).then(log, log); 

另请注意,您可以/应该使用 promise 构造函数来支持 deferreds,因为它是安全的。

于 2014-11-25T10:48:46.180 回答