蓝鸟承诺订单问题



我正在看视频学习MongoDB Express.js VueJS Node.js(MEVN(堆栈。

我想创建一个种子目录,并使用promise函数

//  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)
})
) 
})

我有四个带有种子的表要创建,最后两个表的数据必须在前两个表数据之后创建。(它们是外键(

但每次我运行这个文件时,最后两个表的数据都会首先创建

我能防止这种情况发生的唯一方法是在它们之间添加延迟(1000(。

我想知道是否有任何有效的方法来解决这个问题~

谢谢。

像这样的竞争条件总是由承诺没有正确链接引起的。

应从map回调返回promise:

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

等等。

不从map返回值实际上总是一个错误。它可以通过使用array-callback-returnESLint规则来防止。

如果User.create(user)等是默认配置的Bluebird承诺,则不链接它们也会导致此警告。

我认为您的代码可能失败的原因:

您没有返回Promises,我猜/(User|Song|Bookmark|History).create/g会返回给Promise.all()函数,因为您的映射回调没有返回任何内容。

如果使用带括号的Arrow函数,则需要显式指定返回值(使用familyreturn关键字(。

否则,您可以省略花括号。

我的建议是,使用Promise.then()-Chaining重构您的代码。

举个例子,我建议这样做:

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)
)
)
)
);

最新更新