何时是数据库插入的关键部分?

时间:2018-02-01 23:54:48

标签: javascript node.js sequelize.js

这是我使用sequelize插入数据库的代码。

insertUser: function() { 
    User.build({
        firstName: 'John'
    }).save().then(newUser => {
        const race = Race.build({
            name: 'Spa'
        });
        race.setUser(newUser);
        race.save();
    });
}

我还不熟悉异步/同步javascript关键部分。在插入用户之后我使用Promise,因此我能够获得他的id,因此能够创建具有他的属性的种族。之后我会在保存之前建立并设置外键。

我的问题是:我应该在race.save()之前添加一个新的Promise,等待在保存之前设置外键属性,并避免在没有外键的情况下保存可能的种族?或者来自.then的所有内容(开启,连续运行?为什么?

谢谢:)

2 个答案:

答案 0 :(得分:2)

让我们使用您的代码清理:

User.build({
    firstName: 'John'
}).save().then(newUser => {
    const race = Race.build({
        name: 'Spa'
    });
    console.log("2");
    race.setUser(newUser);
    console.log("3")
    race.save().then(race => {
        console.log("5");
    });
    console.log("4");
});
console.log("1")

每当您执行异步操作(如转到数据库),而不是等待操作完成(阻止)时,节点会继续,以便不浪费可用于执行其他操作的循环。在上面的例子中,我们有几个save()调用。在我们到达第二个console.log之前,我们有一个保存,这意味着该节点将继续并将在最底部记录第一条消息。完成save()调用后,它将在then()块中继续。由于setUser不是异步,它将设置用户然后打印3.当我们再次调用save时,我们将再次访问数据库并在继续打印之前打印4。

答案 1 :(得分:1)

在创建Race之前,您已经在等待User.build.save()的Promise解析(then()的第一个参数是promise成功回调)。在保存使用User.build的已解析返回值创建的竞赛之前,您实际会产生什么承诺?

从语义上讲,您的程序流程是:

  1. 使用firstName属性“John”
  2. 创建一个用户
  3. 等待此用户提交。
  4. 成功保存后,您将返回刚保存的用户对象,将其分配给变量newUser并构建一个名为race的新Race对象,其名称属性为'Spa'
  5. race的用户设置为newUser
  6. 提交race
  7. 如果race的用户是User的外键,那么您已经保证了当前拥有的操作顺序,因为在then()的第一个参数内创建Race意味着您在创建Race之前等待用户提交。

    将其与:

    进行比较
    function() {
        const newUser = User.build({
            firstName: 'John'}).save();
    
        const race = Race.build({
            name: 'Spa'
        });
    
        race.setUser(newUser);
    
        // newUser might not exist before attaching it to race!
    
        race.save();
    
        // if Race requires user as a foreign key, Integrity error
        // can be thrown if newUser didn't exist yet
    }