承诺:当进度更新的数量未知时重构进度

时间:2014-11-25 10:23:12

标签: javascript node.js promise q when-js

在一些主要的承诺库( Q When Bluebird )中已弃用进度处理程序,并且已从新的Promises/A+ spec。虽然我理解取消进展事件背后的原因,但我很难重新考虑以下我已经习惯的模式:

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 :( */

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

那里的任何人都可以帮我实现上述模式而不使用进度事件/处理程序吗?

1 个答案:

答案 0 :(得分: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构造函数来支持延迟,因为它是安全的。