Bluebired Promise Order issue

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


Bluebired 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.




2 Answers
2



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



A promise should be returned from map callback:


map


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.


map


array-callback-return



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


User.create(user)



You're not returning the Promises that I guess /(User|Song|Bookmark|History).create/g return to the Promise.all() function, since your map callback is not returning anything.


/(User|Song|Bookmark|History).create/g


Promise.all()



If you're using Arrow functions with brackets, then you need to explicitly specify the return value (using the familar return keyword).


return



Otherwise you can just omit the curly brackets.



My suggestion is, that you refactor you're code by utilizing Promise .then()-Chaining.


.then()



For you're example, I would suggest something like this:


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

sequelize.sync({
force: true
}).then(() =>
Promise.all(
users.map(user =>
User.create(user)
)
).then(() =>
Promise.all(
songs.map(song =>
Song.create(song)
)
)
).then(() =>
Promise.all(
bookmarks.map(bookmark =>
Bookmark.create(bookmark)
)
)
).then(() =>
Promise.all(
histories.map(history =>
History.create(history)
)
)
)
);





There is no second possibility. await internally chains a promise with then, await bluebirdPromise is equivalent to Promise.resolve(bluebirdPromise).then(...).
– estus
10 hours ago


await


then


await bluebirdPromise


Promise.resolve(bluebirdPromise).then(...)





@estus thanks for the clarification, I didn't know. Cool username btw. I'll update my answer.
– FatalMerlin
10 hours ago






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Keycloak server returning user_not_found error when user is already imported with LDAP

PHP parse/syntax errors; and how to solve them?

How to scale/resize CVPixelBufferRef in objective C, iOS