Асинхронный nodejs и обещания в цикле - PullRequest
0 голосов
/ 15 февраля 2020

У меня есть некоторые проблемы с пониманием асинхронного nodejs в al oop и связанной области видимости, я думаю.

В принципе, я хочу извлечь различные значения и сохранить его в объекте «шаблона», который я буду реализовать каждый l oop и сохранить в массиве обещаний, чтобы использовать его при разрешении.

Может показаться (много) далеко надуманным для реальной цели этого кода, но я изо всех сил пытаюсь понять, почему обещание переменная возвращает только последний элемент каждый l oop, даже если я передаю значение индекса функции и использую его в then () .

Код:

(async ()=>{

let tab = ["a","b","c","d"];
let data = { name:"Random Array", data:null, idx:null};
let promise = {};
let promisesArray = [];

for(let i = 0 ; i < tab.length; i++){
 promise = wait(3000).then(()=>{
   let d = data;
   d.data = tab[i];
   d.idx = i;
   d.success = true;
   console.log(d);
   return d;
   });

   promisesArray.push(promise);
}

let fullData = await Promise.all(promisesArray);
console.log(fullData);

})();

function wait(time){
 return new Promise((resolve,reject)=>{
   setTimeout(resolve,time)
 });
}

Вывод:

[{ name: 'Random Array', data: 'd', idx: 3, success: true },
 { name: 'Random Array', data: 'd', idx: 3, success: true },
 { name: 'Random Array', data: 'd', idx: 3, success: true },
 { name: 'Random Array', data: 'd', idx: 3, success: true }]

Предполагаемый вывод:

[{ name: 'Random Array', data: 'a', idx: 0, success: true },
 { name: 'Random Array', data: 'b', idx: 1, success: true },
 { name: 'Random Array', data: 'c', idx: 2, success: true },
 { name: 'Random Array', data: 'd', idx: 3, success: true }]

Извините, если это какое-то тривиальное знание, но я до сих пор ничего не нашел об этом. Заранее спасибо за ваше время!

1 Ответ

0 голосов
/ 15 февраля 2020

Дело в том, что вы все время используете один и тот же объект data, поэтому в вашем массиве есть 4 абсолютно одинаковых объекта, все из-за этой строки в вашем l oop:

let d = data;

Вы просто присваиваете data d, он не делает копию data, но теперь они оба имеют ссылку на один и тот же data объект. Если вы просто скопировали значение data в d, все будет в порядке:

const d = { ...data }

// or

const d = { name:"Random Array", data:null, idx:null}

// or 

const getData = () => ({ name:"Random Array", data:null, idx:null})
const d = getData()

Надеюсь, это поможет <3 </p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...