蓝鸟承诺订单问题
Bluebird Promise Order issue
我正在观看视频以学习 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)
})
)
})
我有四个带种子的表要创建,最后两个表数据必须在前两个表数据之后创建。 (它们是外键)
但是我每次运行这个文件,都会先创建最后两张表的数据
我能防止这种情况的唯一方法是在它们之间添加 delay(1000)。
请问有没有什么有效的方法可以解决这个问题~
谢谢。
像这样的竞争条件总是由 promise 没有正确链接引起的。
应从 map
回调中返回承诺:
await Promise.all(
users.map( user => User.create(user))
);
等等
不从 map
返回值几乎总是一个错误。可以使用 array-callback-return
ESLint rule.
来防止
如果 User.create(user)
等是具有默认配置的 Bluebird 承诺,则不链接它们也会导致 this warning。
我假设您的代码可能失败的原因:
你没有 return 将我猜 /(User|Song|Bookmark|History).create/g
return 的 Promise 发送到 Promise.all()
函数,因为你的地图回调不是 return任何东西。
如果您使用带括号的箭头函数,则需要明确指定 return 值(使用熟悉的 return
关键字)。
否则你可以省略大括号。
我的建议是,使用 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)
)
)
)
);
我正在观看视频以学习 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)
})
)
})
我有四个带种子的表要创建,最后两个表数据必须在前两个表数据之后创建。 (它们是外键)
但是我每次运行这个文件,都会先创建最后两张表的数据
我能防止这种情况的唯一方法是在它们之间添加 delay(1000)。
请问有没有什么有效的方法可以解决这个问题~
谢谢。
像这样的竞争条件总是由 promise 没有正确链接引起的。
应从 map
回调中返回承诺:
await Promise.all(
users.map( user => User.create(user))
);
等等
不从 map
返回值几乎总是一个错误。可以使用 array-callback-return
ESLint rule.
如果 User.create(user)
等是具有默认配置的 Bluebird 承诺,则不链接它们也会导致 this warning。
我假设您的代码可能失败的原因:
你没有 return 将我猜 /(User|Song|Bookmark|History).create/g
return 的 Promise 发送到 Promise.all()
函数,因为你的地图回调不是 return任何东西。
如果您使用带括号的箭头函数,则需要明确指定 return 值(使用熟悉的 return
关键字)。
否则你可以省略大括号。
我的建议是,使用 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)
)
)
)
);