Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/379.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/2/node.js/38.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_Node.js_Es6 Promise - Fatal编程技术网

Javascript 如何基于承诺生成异步函数

Javascript 如何基于承诺生成异步函数,javascript,node.js,es6-promise,Javascript,Node.js,Es6 Promise,问题在于,该函数不会等到映射完成 我认为解决办法就是承诺 但是我不知道如何使用这个功能 exports.createProduct = (data) => { var imgS3arr = []; //array which we waiting for data.img.map((img, i) => { fetch.remote(img).then((base) => { var buf = Buffer.from(base[0], 'bas

问题在于,该函数不会等到映射完成

我认为解决办法就是承诺 但是我不知道如何使用这个功能

exports.createProduct = (data) => {
  var imgS3arr = []; //array which we waiting for
  data.img.map((img, i) => {
    fetch.remote(img).then((base) => {
        var buf = Buffer.from(base[0], 'base64');

        var imgS3 = {
            Key: data.title + i, //TODO: add random
            Body: buf,
            ContentEncoding: 'base64',
            ContentType: 'image/jpeg'
        };

        s3Bucket.putObject(imgS3, function (err, data) {
            if (err) {
                console.log(err);
                console.log('Error uploading data: ', data);
            } else {
                var params = this.request.params;
                var region = this.request.httpRequest.region;
                imgS3arr.push('https://s3-' + region + '.amazonaws.com/' + params.Bucket + '/' + params.Key)
            }
        }
      );
    }).catch((reason) => { });
});

//next part of code must be executed when all items pushed to 'imgS3arr'

const product = new Product({
    title: data.title,
    img: imgS3arr,  //we waiting for this array
});
return product.save((function (err) {
    if (err) {
        console.log(err);
    } else {
        console.log('Added new! \n' + product);
    }
  }));
}

有人能帮我解决这个问题吗?

你可以这样做:

// returns a promise that is resolved when everything is done
//    or rejected with the first error that occurs
exports.createProduct = (data) => {
    var imgS3arr = []; //array which we waiting for
    return Promise.all(data.img.map((img, i) => {
        return fetch.remote(img).then((base) => {
            var buf = Buffer.from(base[0], 'base64');

            var imgS3 = {
                Key: data.title + i, //TODO: add random
                Body: buf,
                ContentEncoding: 'base64',
                ContentType: 'image/jpeg'
            };

            return s3Bucket.putObject(imgS3).promise().then(function(data) {
                // given other changes here and unfamiliarity with this code
                // I'm unsure if `this` still has the right value in it here
                var params = this.request.params;
                var region = this.request.httpRequest.region;
                imgS3arr.push('https://s3-' + region + '.amazonaws.com/' + params.Bucket + '/' + params.Key)
            }).catch(function(err) {
                // log error, then rethrow to keep the promise rejected
                console.log(err);
                console.log('Error uploading data: ', data);
                throw err;
            });
        });
    })).then(function() {
            const product = new Product({
                title: data.title,
                img: imgS3arr, //we waiting for this array
            });
            // use database interface that uses promises, not plain callbacks
            return product.save(...);
        }
    });
}
所做更改的摘要和解释:

  • data.img.map()
    的内部,返回一个承诺,以便
    .map()
    创建一个承诺数组
  • 在承诺数组中使用
    Promise.all()
    ,以了解承诺何时完成
  • 切换到
    s3Bucket.putObject(imgS3.promise()
    ,这样我们就可以使用promises而不是普通回调
  • 记录后在
    .catch()
    中重新显示错误,因此承诺将被拒绝
  • 将要等待的代码放入
    Promise.all().then()处理程序中
  • product.save()
    切换到使用承诺而不是普通回调的数据库接口,以便您可以直接链接该承诺(留给OP去做,因为我们甚至不知道它是什么数据库)

  • 您将异步与常规回调和承诺混合在一起。首先要做的是将这段代码中的所有异步操作转换为承诺。然后,用
    Promise.all()
    等待将是微不足道的。