1
const wiki = require('wikijs').default;
const { writeFileSync } = require("fs")
const dates = require("./getDates")
//December_23
for (let i = 0; i < dates.length; i++){
        wiki()
            .page(dates[i])
            .then(page => page.content()).then((value => {
                writeFileSync(`./data/${dates[i]}.json`,value)
                console.log(`${dates[i]} imported`)
        }
        )
        ).catch((err) => console.error(`${dates[i]} error\n${err}`))
}

I'm trying to get data from Wikipedia with wikijs using for loop. But for loop didnt wait for promise end how can i solve this

GreXLin85
  • 97
  • 1
  • 10
  • Does this answer your question? [Wait promise inside for loop](https://stackoverflow.com/questions/48014050/wait-promise-inside-for-loop) – Ivar Oct 24 '20 at 18:06
  • Could you be more specific why the fact that it does not wait for the promise is a problem for you? Is it because by the time the promises end `i` ends up being `dates.length - 1` for all of them? – silvenon Oct 24 '20 at 18:53

3 Answers3

2

As you said, your loop execute your promise in the loop synchronously not asynchronously and what happens here is that your callback will be called with last index i in the loop because your loop will finish work and your callback will be called later

You can work around this by creating a closure to save the index for every callback:

One solution is to use forEach as it creates its own closure:

dates.forEach((date, i) => {
   wiki.page(date).then(..........)
})

another solution is to create a IIFE inside your loop:

for(let i = 0; i < dates.length; i++  ) {
  (function(i){
    //Your logic
  })(i)
}
Saher Elgendy
  • 1,519
  • 4
  • 16
  • 27
  • 1
    I believe this is the correct answer. The OP wasn't clear about _why_ it was the problem that the loop wasn't waiting for promises, but this is probably it. – silvenon Oct 24 '20 at 18:56
0

try map instead of for loop and assign it to a promises variable and do Promise.all(promises) to resolve all promises


const promises = dates.map((date)=>{
   return wiki().page(date)
})

Promise.all(promises).then((data)=>{
})

Jithin Zachariah
  • 313
  • 3
  • 13
0

You can use Promise.all.

const wiki = require('wikijs').default;
const { writeFileSync } = require("fs")
const dates = require("./getDates")
//December_23

const promises = []
for (let i = 0; i < dates.length; i++) {
  promises.push(
    wiki()
    .page(dates[i])
    .then(page => page.content())
    .then(value => {
      writeFileSync(`./data/${dates[i]}.json`,value)
      console.log(`${dates[i]} imported`)
    })
  )
}

Promise.all(promises)
.then(res => {
  // do something
})
michael
  • 4,053
  • 2
  • 12
  • 31