Javascript asyn c получить запрос внутри цикла - PullRequest
0 голосов
/ 17 января 2020

У меня есть массив объектов, который выглядит следующим образом:

[ { firstName: 'Mike', lastName: 'Jones' },
  { firstName: 'Joe', lastName: 'Smith' },
  { firstName: 'Bob', lastName: 'Johnson' } ]

Мне нужно передать этот массив функции, которая собирается добавить поле "middleName" для каждого объекта и значение для middleName , Функция получает отчество, делая асинхронный запрос http.get в Node. И в этом заключается проблема. Я не могу заставить это работать независимо от того, как я пытаюсь.

Ранее кто-то предлагал oop вот так:

array.forEach(function (obj) {
        GetMiddleName(obj, function (person) {
            obj.MiddleName = person;
        });
    });

Но это не работает из-за асин c характер вызова get в функции GetMiddleName. Может кто-нибудь показать мне короткую, простую функцию, которая будет делать то, что мне нужно?

Ответы [ 4 ]

1 голос
/ 17 января 2020

Создайте массив Promises, вызовите Promise.all для этого массива, а затем вставьте отчество к каждому:

const getMiddleNameProm = obj => new Promise((resolve) => {
  GetMiddleName(obj, resolve);
});
Promise.all(arr.map(getMiddleNameProm))
  .then((middleNames) => {
    for (let i = 0; i < middleNames.length; i++) {
      arr[i].MiddleName = middleNames[i];
    }
    // do stuff with populated arr here
  });
});

0 голосов
/ 17 января 2020

Вы можете использовать пакет async для обработки асинхронных итераций, используя asyn c framework .

Используя async.eachOf без функции обратного вызова (возвращает обещание). Примечание: доступно из версии 3.x.

Возвращает:
обещание, если обратный вызов пропущен

Тип: обещание

const async = require('async');

let items = [
    { firstName: 'Mike', lastName: 'Jones' },
    { firstName: 'Joe', lastName: 'Smith' },
    { firstName: 'Bob', lastName: 'Johnson' }
];

async.eachOf(items, (item, index, callback) => {
    GetMiddleName(item, function (person) {
        item.MiddleName = person;
    })
      .then(result => {

          console.log('this is result:', result);
          callback();
      });
})
.then(() => {
   console.log('All items updated');
});

Или вы можете справиться с такой функцией обратного вызова:

async.eachOf(items, (item, index, callback) => {
    GetMiddleName(item, function (person) {
        item.MiddleName = person;
    })
      .then(result => {

          console.log('this is result:', result);
          callback();
      });
},
  (err) => {
    if (err)
        throw new Error(err);
    else
        console.log('All items updated');
  });
0 голосов
/ 17 января 2020

Вам нужно создать массив обещаний, а затем разрешить их. Я думаю, что некоторые ответы здесь верны, но это чище и проще для понимания, особенно если вы новичок в обещаниях.

let promises = [];

array.forEach(function (item) {
  let promise = new Promise(function (resolve) {
    GetMiddleName(obj, function (person) {
        obj.MiddleName = person;
        resolve();
    });
  });

  promises.push(promise);
});

Promise.all(promises).then(function () {
  // Do something after all values/promises have been resolved
  // If not just leave it at Promise.all(promises)
});
0 голосов
/ 17 января 2020

Это должно работать

let arrData = [ { firstName: 'Mike', lastName: 'Jones' },
  { firstName: 'Joe', lastName: 'Smith' },
  { firstName: 'Bob', lastName: 'Johnson' } ];

  function getMiddleName(arr){
    arr.forEach(ar => {
        //this will be your async request that gets the usrename
        asynRequest.then(person => {
        arr.MiddleName = person;
      });
    });
  }

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