最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Push to a new array inside a mappromise - Stack Overflow

programmeradmin5浏览0评论

Here is a simplified version of my current setup.

When running this code you'll notice that modifying the changes array also manipulates the original referrals array. Is this because I'm pushing to the changes array inside a map function? How can I modify the changes array without modifying the referrals array?

var referrals = [
  {
    id: 1,
    name: 'John',
    change: true
  },
  {
    id: 2,
    name: 'Sally',
    change: false
  },
  {
    id: 3,
    name: 'Kim',
    change: true
  }
];

var changes = [];

var process = referrals.map(function(referral) {
  return new Promise(function(resolve, reject) {
    if (referral.change) {
      changes.push(referral);
    }
    resolve();
  });
});

Promise.all(process).then(function() {
  console.log('referrals before:', referrals);
  changes = changes.map(function(change) {
    change.change_id = change.id;
    delete change.id;
    return change;
  });

  console.log('changes:', changes);
  console.log('referrals after:', referrals);
});

Here is a simplified version of my current setup.

When running this code you'll notice that modifying the changes array also manipulates the original referrals array. Is this because I'm pushing to the changes array inside a map function? How can I modify the changes array without modifying the referrals array?

var referrals = [
  {
    id: 1,
    name: 'John',
    change: true
  },
  {
    id: 2,
    name: 'Sally',
    change: false
  },
  {
    id: 3,
    name: 'Kim',
    change: true
  }
];

var changes = [];

var process = referrals.map(function(referral) {
  return new Promise(function(resolve, reject) {
    if (referral.change) {
      changes.push(referral);
    }
    resolve();
  });
});

Promise.all(process).then(function() {
  console.log('referrals before:', referrals);
  changes = changes.map(function(change) {
    change.change_id = change.id;
    delete change.id;
    return change;
  });

  console.log('changes:', changes);
  console.log('referrals after:', referrals);
});

Share Improve this question asked Aug 16, 2017 at 19:47 floatleftfloatleft 6,58115 gold badges45 silver badges55 bronze badges 3
  • 3 You're not changing the referrals Array. You're changing the Objects it contains. And you'll have the same results without using Promises. When you push your Objects into the changes Array, you're actually pushing references to the Objects that are in the referrals Array. Not copies of them, which is what you seem to think. So then, when you change a property of these Objects, these differences will show everywhere these Objects are referenced. To solve this, look up "JS clone Object" – blex Commented Aug 16, 2017 at 19:53
  • WTH are you using promises at all? There's nothing asynchronous in your code. – Bergi Commented Aug 16, 2017 at 21:11
  • @Bergi I need a promise in my actual code because I'm going some requests between each object. I slimmed down my posted example. – floatleft Commented Aug 16, 2017 at 21:42
Add a ment  | 

2 Answers 2

Reset to default 3

You just need to create a deep copy of the inner objects, you can do it with lodash deepClone, or spread operator.

Something like that:

var referrals = [
{
  id: 1,
  name: 'John',
  change: true
},
{
  id: 2,
  name: 'Sally',
  change: false
},
{
  id: 3,
  name: 'Kim',
  change: true
}
];

var changes = [];

var process = referrals.map(function(referral) {
  return new Promise(function(resolve, reject) {
    if (referral.change) {
      changes.push({...referral}); // You will create a copy here.
    }
    resolve();
  });
});

Promise.all(process).then(function() {
  console.log('referrals before:', referrals);
  changes = changes.map(function(change) {
  change.change_id = change.id;
  delete change.id;
  return change;
});

console.log('changes:', changes);
console.log('referrals after:', referrals);
});

Thanks blex for walking me through what was going on here. Essentially when I was pushing the object to a new array, I was pushing the entire reference and not just a copy. Using Object.assign to clone the object solves my issue.

Here is the entire edit for reference:

var referrals = [
  {
    id: 1,
    name: 'John',
    change: true
  },
  {
    id: 2,
    name: 'Sally',
    change: false
  },
  {
    id: 3,
    name: 'Kim',
    change: true
  }
];

var changes = [];

var process = referrals.map(function(referral) {
  new Promise(function(resolve, reject) {
    if (referral.change) {
      changes.push(Object.assign({}, referral));
    }
    resolve();
  });
});

Promise.all(process).then(function() {
  console.log('referrals before:', referrals);
  changes = changes.map(function(change) {
    change.change_id = change.id;
    delete change.id;
    return change;
  });

  console.log('changes:', changes);
  console.log('referrals after:', referrals);
});

发布评论

评论列表(0)

  1. 暂无评论