Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将参数传递给在循环中创建的承诺_Javascript_Es6 Promise - Fatal编程技术网

Javascript 将参数传递给在循环中创建的承诺

Javascript 将参数传递给在循环中创建的承诺,javascript,es6-promise,Javascript,Es6 Promise,我正在写一个函数,它可以批量下载带有请求包的图像。 下载部分可以工作,但我在将参数传递到Promise数组时遇到了问题 函数下载图像(数据){ var承诺=[]; var承诺、本地、id、url; 用于(数据中的var i){ (职能(一){ local=“public/images/”.concat(数据[i].id,.png”); url=数据[i]。img\u url id=数据[i].id promise=request.get({ url:url, 本地:本地,, id:id, 编码

我正在写一个函数,它可以批量下载带有请求包的图像。 下载部分可以工作,但我在将参数传递到Promise数组时遇到了问题

函数下载图像(数据){
var承诺=[];
var承诺、本地、id、url;
用于(数据中的var i){
(职能(一){
local=“public/images/”.concat(数据[i].id,.png”);
url=数据[i]。img\u url
id=数据[i].id
promise=request.get({
url:url,
本地:本地,,
id:id,
编码:“二进制”
},函数(err,res){
如果(!err&&res.statusCode==200){
fs.writeFile(本地、res.body、{
编码:“二进制”
},(错误)=>{
如果(!err){
doSomething()
}否则{
console.log(“下载图像时出错”)
}
})
}
})
承诺。推动(承诺)
})(一)
}
承诺。所有(承诺);

}
我建议简化如下:

// 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);
}
原始问题:

  • 从不使用for/in迭代数组
  • local、url、id等变量在太高的范围内声明,因此每次调用循环都会破坏这些值
  • 错误未正确传播回顶层(调用方可能不知道某些错误)
  • 注:

  • 在请求承诺库中,使用
    request.get().then()
    将自动为您检查2xx状态,如果没有,则拒绝,这样您就可以在使用
    时删除该代码。then()
    而不是普通回调
  • 通常,您不希望将承诺与普通回调混合在一起,因为错误传播变得很困难。因此,我创建了一个预期版本的
    fs.writeFile()
    。如果使用Bluebird promise库,它将立即生成整个模块的promisified版本
  • 从初始数组生成一个1对1数组是
    .map()
    的设计目的。它还为你提供了一个函数闭包,这样你就不必创造自己的生活
  • 循环中异步回调中使用的变量必须适当地确定范围(尽可能地局部),以便它们不会被循环的其他迭代覆盖

  • 呃,不如在循环体中声明变量
    local
    id
    url
    ,就像你对
    i
    所做的那样?!
    请求
    是否实际返回承诺?你不需要吗?我这样问是因为我知道npm上有一个单独的包,专门称为
    请求承诺
    。假设
    数据
    是一个数组:使用
    映射
    也可以最简洁地解决您的问题。@Andy为什么您认为这不是重复的?当然,
    get
    writeFile
    的promission也可能会有问题,但这些似乎不是OP想要的。他的主要问题是:“我在将参数传递到Promise数组时遇到问题”:如果没有要添加的承诺,则将承诺添加到承诺数组。感谢您的精彩回答和附加说明!它开始有点条理,但越来越糟:)还有很多东西要学,非常感谢!