Promise.all没有按预期工作

时间:2018-05-14 05:23:37

标签: javascript node.js promise

我希望Promise.all代码返回

{ constant: 'x1' }
{ constant: 'x2' }
{ constant: 'x3' }

但我有这个:

{ constant: 'x1' }
{ constant: 'x12' }
{ constant: 'x123' }

为什么会这样?我似乎无法看到在哪里'常数'正在积累。

这是一个简化的视图 - 我实际上在" testFN"

中更新/创建了一个文档

感谢

function testFN(blob, array, iter){
    var newBlob = blob;
    newBlob.constant = blob.constant+array.num
    console.log(newBlob);
    return products.findOneAndUpdate ....   
}

exports.updateProductId = function(req, res) {

    var blob = {"constant":"x"};
    var arr = { key1:{num: "1"}, key2:{num: "2"}, key3:{num: "3"}};
    var fnArr = [];

    Object.keys(arr).forEach(function(key, i) {
       fnArr.push(testFN(blob, arr[key], i));
    });

    return Promise.all(fnArr)
    .then(function(success){
        console.log(success);
    })
    .catch(function(error){
        console.log(error);
    })

})

2 个答案:

答案 0 :(得分:1)

非基元通过引用传递 - 您可以将任何表示对象的变量视为对内存位置的引用。所以,在testFN

function testFN(blob, array, iter){
  var newBlob = blob;
  newBlob.constant = blob.constant+array.num

newBlob指向内存中与blob参数相同的位置,因此当您更改newBlob.constant时,您也会更改原始blob.constant(因为它们是同一个对象)。您可以通过将blob true 副本分配给newBlob来解决此问题:

function testFN(blob, array, iter){
  var newBlob = JSON.parse(JSON.stringify(blob));
  newBlob.constant = blob.constant + array.num;
  console.log(newBlob);
  return newBlob;
}
var blob = {"constant":"x"};
var arr = { key1:{num: "1"}, key2:{num: "2"}, key3:{num: "3"}};
var fnArr = [];

Object.keys(arr).forEach(function(key, i) {
  fnArr.push(testFN(blob, arr[key], i));
});

Promise.all(fnArr)
  .then(function(success){
  console.log(success);
})
  .catch(function(error){
  console.log(error);
})

这与Promise.all无关。无论如何,这些代码都不是异步的。

答案 1 :(得分:-2)

Promise.all可以使用Promises数组更改你的函数“testFN”以返回Promise。

function testFN(blob, array, iter){
    return new Promise(function(resolve, reject) {
       var newBlob = blob;
       newBlob.constant = blob.constant+array.num;
       console.log(newBlob);
       resolve();
    });
}

但是如果你在这种情况下需要Promise.all,你可能会看到什么。因为你这里没有任何异步操作