我正在编写一个批量下载带有请求包的图像的功能。 下载部分可以工作,但我遇到了将参数传递到Promise数组的问题。
function downloadImages(data) {
var promises = [];
var promise, local, id, url;
for (var i in data) {
(function(i) {
local = "public/images/".concat(data[i].id, ".png");
url = data[i].img_url
id = data[i].id
promise = request.get({
url: url,
local: local,
id: id,
encoding: 'binary'
}, function(err, res) {
if (!err && res.statusCode === 200) {
fs.writeFile(local, res.body, {
encoding: 'binary'
}, (err) => {
if (!err) {
doSomething()
} else {
console.log("Error Downloading image")
}
})
}
})
promises.push(promise)
})(i)
}
Promise.all(promises);
}
当我运行它时,数组中的所有参数都会解析为最后一个条目,因此它被下载(data.length)次。
我尝试了几件事,但无法接近解决方案。有什么基本的我做错了或者相当简单的东西?非常感谢一些帮助!
答案 0 :(得分:1)
我建议像这样简化:
// make promisified version of fs.writeFile()
fs.writeFileAsync = function(fname, data, options) {
return new Promise((resolve, reject) => {
fs.writeFile(fname, data, options, err => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
}
function downloadImages(data) {
let promises = data.map(obj => {
let local = "public/images/".concat(obj.id, ".png");
let url = obj.img_url;
let id = obj.id;
return request.get({url, local, id, encoding: 'binary'}).then(imgData => {
return fs.writeFileAsync(local, imgData, {encoding: 'binary'}).then(doSomething).catch(err => {
console.log("Error Downloading image");
// propagate error after logging it
throw err;
});
});
});
return Promise.all(promises);
}
原始问题:
注意:
request.get().then()
将自动检查您的2xx状态,如果不是,则拒绝使用.then()
而不是普通回调删除该代码。fs.writeFile()
的宣传版。如果使用Bluebird promise库,它将立即生成整个模块的promisified版本。.map()
的目的。它还为您提供了一个功能关闭,因此您不必自己制作IIFE。