简体   繁体   中英

Promise.all not working at expected

I expected the Promise.all code to return

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

but instead I have this:

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

Why would this happen? I can not seem to see where 'constant' is accumulating.

This is a simplified view - I actually updated/create a document in "testFN"

thanks

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

})

Non-primitives are passed by reference - you can think of any variable that represents an object as a reference to a memory location . So, in testFN :

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

newBlob points to the same place in memory as the blob parameter, so when you change newBlob.constant , you change the original blob.constant as well (since they're the same object). You can fix it by assigning a true copy of blob to 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); }) 

This has nothing to do with Promise.all . None of this code is asynchronous anyway.

Promise.all can work with array of Promises change you function "testFN" to return 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();
    });
}

But you might what to see if you need Promise.all in this case at all. Bcause you do not have any Async operation here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM