Promises.all не запускается после циклического прохождения нескольких запросов ajax - PullRequest
0 голосов
/ 14 декабря 2018

Я импортирую файл json и перебираю объект.У каждого объекта есть массив с идентификаторами событий, которые я также перебираю.В этом forEach я помещаю функцию-обертку, которая возвращает Promise в массив promises

. После зацикливания всех объектов я выполняю promise.all() для массива promises.Но странным образом все, что я делаю после этого цикла, не выполняется.

const fs = require('fs')
const promisify = require('util').promisify
const rp = require('request-promise')
const readFile = promisify(fs.readFile)
const filePath = 'json/results.json'

let promises = []

function init() {
  readFile(filePath, 'utf8')
  .then(file => {
    const json = JSON.parse(file)

    for (const country of json) {
      if (country.eventIDs.length === 0) return

      country.eventIDs.forEach(id => promises.push(getEventData(country, id)))
    }

// nothing here is executed,  
    console.log('this is not fired')

    Promise.all(promises)
           .then(results => writeFile(results))
           .catch( err => console.log(err))
  })
  .catch(err => console.log(err))
}

getEventData = (country, id) => new Promise((resolve, reject) => {

  setTimeout(() => {
    rp(url)
    .then((results) => {      
      resolve ({
        ...results
      })
    })
    .catch((err) => reject(`getEventData Error:\n ${err}`))
  }, 2000)
})

writeFile = (results) => {
  const json = JSON.stringify(results)
  // const date = new Date()
  // const filename = `${date.getTime()}-all-event-ids.json`
  const filename = `results-allevents.json`
  fs.writeFile(`json/${filename}`, json, 'utf8', () => console.log(`Succesfully written: ${filename}`))
}

init()

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

После расследования главной проблемой была строка:

if (country.eventIDs.length === 0) return

(и многие другие решались с помощью комментариев).

Проблема, поясняющая, чтоявляется то, что return не пропускает зацикленный элемент (как, возможно, ожидалось), а скорее возвращает void в обратном вызове then, поэтому пропускает дальнейшее выполнение этого блока.

Для того, чтобы "пропустите элемент, если это условие истинно, просто сделайте это вместо

    for (const country of json) {
      if (country.eventIDs.length > 0) { 
          country.eventIDs.forEach(id => promises.push(getEventData(country, id))) 
      }
    }
0 голосов
/ 14 декабря 2018

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

const results = [];

country.eventIDs.forEach(id => promises.push(getEventData(country, id)
.then(res =>  results.push(res));

Promise.all(promises).then(()=> writeFile(results))

Пример Stackblitz

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