Clash 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)
)
)
)
);
await
then
await bluebirdPromise
Promise.resolve(bluebirdPromise).then(...)
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.
There is no second possibility.
await
internally chains a promise withthen
,await bluebirdPromise
is equivalent toPromise.resolve(bluebirdPromise).then(...)
.– estus
10 hours ago