gpt4 book ai didi

javascript - 将参数传递给循环创建的 Promise

转载 作者:行者123 更新时间:2023-11-29 23:38:06 25 4
gpt4 key购买 nike

我正在编写一个函数,使用请求包批量下载图像。下载部分有效,但我在将参数传递到 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) 次。

我尝试了一些方法,但无法更接近解决方案。我做错了什么根本性的事情还是相当简单的事情?非常感谢您的帮助!

最佳答案

我建议像这样简化:

// 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);
}

原始问题:

  1. 永远不要用 for/in 迭代数组
  2. 诸如 local、url、id 之类的变量在过高的范围内声明,因此每次循环调用都会破坏这些值
  3. 错误没有被正确传播回顶层(调用者可能不知道某些错误)

注意事项:

  1. 在请求- promise 库中,使用 request.get().then()将自动为您检查 2xx 状态,如果不是则拒绝,因此您可以在使用 .then() 时删除该代码而不是简单的回调。
  2. 一般来说,您不希望将 promise 与普通回调混合使用,因为错误传播变得困难。所以,我创建了一个 promise 版本 fs.writeFile() .如果使用 Bluebird promise 库,它将立即生成整个模块的 promise 版本。
  3. 从初始数组生成一对一数组是 .map()被设计来做。它还为您提供了一个函数闭包,因此您不必制作自己的 IIFE。
  4. 循环中异步回调中使用的变量必须适当限定范围(尽可能局部),这样它们就不会被循环的其他迭代覆盖。

关于javascript - 将参数传递给循环创建的 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45905374/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com