蓝鸟承诺订单问题

时间:2018-07-25 11:26:56

标签: javascript node.js promise bluebird

我正在观看视频以学习 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)。

我想知道是否存在解决此问题的有效方法〜

谢谢。

2 个答案:

答案 0 :(得分:3)

像这样的比赛条件总是由未正确链接诺言引起的。

应从map回调中返回一个承诺:

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

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

如果User.create(user)等是使用默认配置的Bluebird承诺,则不链接它们也会导致this warning

答案 1 :(得分:1)

我的假设为什么您的代码可能会失败:

由于您的地图回调未返回任何内容,因此您没有将/(User|Song|Bookmark|History).create/g返回到Promise.all()函数的状态返回。

如果您使用带有括号的Arrow函数,则需要显式指定返回值(使用熟悉的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)
            )
        )
    )
);