Search code examples
javascriptnode.jspromisebluebird

Bluebird Promise Order issue


I am watching videos to learn MongoDB Express.js VueJS Node.js (MEVN) stack.

And I want to create a seed directory and also use promise functions

//  const delay = require('delay')
const Promise = require('bluebird') 
const songs = require('./songs.json')
const users = require('./users.json')
const bookmarks = require('./bookmarks.json')
const historys = require('./history.json')

sequelize.sync({ force: true })
  .then( async function () {

    await Promise.all(
        users.map( user => {
            User.create(user)
        })
    ) 
    await Promise.all(
        songs.map( song => {
            Song.create(song)
        })
    )

     //I have to add this line
     //  ---> await delay(1000) 

    await Promise.all(
        bookmarks.map( bookmark => {
            Bookmark.create(bookmark)
        })
    )

    await Promise.all(
        historys.map( history => {
            History.create(history)
        })
    ) 
})

I have four tables with seeds to create, and the last two tables data must be created after the former two tables data. (They are foreign keys)

But every time I run this file, the last two tables data will be created first

The only way I can prevent this is to add delay(1000) between them.

I am wondering if there exists any efficient way to solve this issue~

Thank you.


Solution

  • Race conditions like this one is always caused by that promises weren't properly chained.

    A promise should be returned from map callback:

    await Promise.all(
        users.map( user => User.create(user))
    );
    

    etc.

    Not returning a value from map is virtually always a mistake. It can be prevented by using array-callback-return ESLint rule.

    If User.create(user), etc. were Bluebird promises with default configuration, not chaining them would also result in this warning.