Node.js 在下载模块中使用承诺
我用蓝鸟做承诺 我正试图向你保证这件事 以下是我的实现:Node.js 在下载模块中使用承诺,node.js,download,promise,bluebird,Node.js,Download,Promise,Bluebird,我用蓝鸟做承诺 我正试图向你保证这件事 以下是我的实现: Promise = require('bluebird'), download = require('download'); var methodNameToPromisify = ["download"]; function EventEmitterPromisifier(originalMethod) { // return a function return function promisified() {
Promise = require('bluebird'),
download = require('download');
var methodNameToPromisify = ["download"];
function EventEmitterPromisifier(originalMethod) {
// return a function
return function promisified() {
var args = [].slice.call(arguments);
// Needed so that the original method can be called with the correct receiver
var self = this;
// which returns a promise
return new Promise(function(resolve, reject) {
// We call the originalMethod here because if it throws,
// it will reject the returned promise with the thrown error
var emitter = originalMethod.apply(self, args);
emitter
.on("response", function(data) {
resolve(data);
})
.on("data ", function(data) {
resolve(data);
})
.on("error", function(err) {
reject(err);
})
.on("close", function() {
resolve();
});
});
};
};
download = { download: download };
Promise.promisifyAll(download, {
filter: function(name) {
return methodNameToPromisify.indexOf(name) > -1;
},
promisifier: EventEmitterPromisifier
});
然后使用它:
return download.downloadAsync(fileURL, copyTo, {});
我的问题是,它没有下载所有的文件(我有一个列表发送到此函数),我做错了什么?发射器确实会发出多个数据事件,它接收到的每个数据块对应一个。但是,a只代表一个未来值,在您的情况下,您希望它是完整的响应
resolve
应该只调用一次,以使用传递的值实现承诺,然后进行结算。进一步的呼叫将没有任何效果-这就是为什么您只得到列表的前几部分
相反,您将需要累积所有数据,当流结束时,您可以用所有数据实现承诺
var Promise = require('bluebird'),
download = require('download'),
Buffer = require('buffer'); // should be global anyway
exports = {
downloadAsync: function promisifiedDownload() {
var args = arguments, self = this;
return new Promise(function(resolve, reject) {
// We call the originalMethod here because if it throws,
// it will reject the returned promise with the thrown error
var emitter = download.apply(self, args);
var buffers = [];
emitter.on("data", function(data) {
buffers.push(data);
}).on("error", function(err) {
reject(err);
}).on("close", function() {
resolve(Buffer.concat(buffers));
});
});
};
};
请注意,当您只想提出一个方法时,使用promisifyAll
是非常荒谬的。为了简单起见,我省略了它
您还可以侦听传入对象,并将
数据
侦听器直接附加到它。然后,您可以使用而不是close
是否有意(a)download={download:download}代码>覆盖download=require('download')代码>,和(b)。on(“数据”,…)
中有这个空间吗?我的错,我会尝试修复它。虽然Angle文档中的示例完整地解释了它(如上所述),但想必。on(“错误”,拒绝)
也可以工作?@Bergi,我必须删除它工作所需的(“缓冲区”),谢谢!这让事情变得更清楚了。啊!我的意思是上面的“Bluebird”文档,而不是“Angular”@agam360:Hm,我说“Buffer
类是一个全局类,这使得人们很少需要要求('Buffer')
”,但我看不出它有什么问题。我的参考只是Bluebird API,在这一节中找到“function EventEmitterCompomissifier”。