【问题标题】:Promises in Sequelize: how to get results from each promiseSequelize 中的 Promise:如何从每个 Promise 中获取结果
【发布时间】:2014-03-10 02:23:41
【问题描述】:

在续集中 >=1.7 we can use promises

你能解释一下我如何在这段代码中从每个用户那里获取值吗:

var User = sequelize.define("user", {
  username: Sequelize.STRING
})


User
  .sync({ force: true })
  .then(function() { return User.create({ username: 'John' }) })
  .then(function(john) { return User.create({ username: 'Jane' }) })
  .then(function(jane) { return User.create({ username: 'Pete' }) })
  .then(function(pete) {
    console.log("we just created 3 users :)")
    console.log("this is pete:")
    console.log(pete.values)

    // what i want:
    console.log("this is jane:")
    console.log(jane.values)

    console.log("this is john:")
    console.log(john.values)
  })

UPD

所有值都需要设置与其他模型的关联。 其实我需要一些这样的代码:

User.hasMany(Group)
Group.hasMany(User)

User
  .sync({ force: true })
  .then(function() { return User.create({ username: 'John' }) })
  .then(function(john) { return User.create({ username: 'Jane' }) })
  .then(function(jane) { return User.create({ username: 'Pete' }) })
  .then(function(pete) { return Group.findOrCreate({id: 1}) })
  .then(function(group) {return group.setUsers([john, jane, pete])})
  .then(function(result) { console.log(result)})
})

【问题讨论】:

  • 我从未听说过 sequelize,但 sync({force:true}) 看起来你不需要异步承诺 :-)
  • 其实sync({force:true})例如在项目启动时调用这个方法可以去掉
  • sync 在这种情况下与 Promise 无关;这是一个强制创建表的 sequelize 选项。

标签: javascript promise sequelize.js bluebird


【解决方案1】:

Bluebird 方式是collection helper functions

如果您想并行创建它们,请使用map

User.sync({ force: true })
  .then(function() {
    return Promise.map( ['John', 'Jane', 'Pete'], function(name) {
      return User.create({ username: name });
    })
  }).spread(function(john, jane, pete) {
    console.log("we just created 3 users :)")
    console.log("this is john:")
    console.log(john.values)
    console.log("this is jane:")
    console.log(jane.values)
    console.log("this is pete:")
    console.log(pete.values)
  })

如果您需要连续创建它们,只需将其更改为mapSeries (3.0+)。

如果数组不需要是动态的,并且您只想像示例中那样通过承诺链传递共享值,请查看How do I access previous promise results in a .then() chain?

【讨论】:

  • 只想提一下.sync({ force: true })会删除当前数据库中的所有表。小心!
  • @wprl:我不知道续集。我应该(可以)忽略这个调用吗?
  • @Biergi,查看同步文档:github.com/sequelize/sequelize/wiki/… 您可能仍想同步,但每次调用强制选项时都会删除表。真的你想在生产中使用迁移,但我在研究中还没有达到这一点:)
【解决方案2】:

不使用额外的库(如果您需要维护创建的顺序),您可以通过在包含值的封闭范围内创建变量来做到这一点:

var created = {};
User
  .sync({ force: true })
  .then(function() { return User.create({ username: 'John' }) })
  .then(function(john) { created.john = john; return User.create({ username: 'Jane' }) })
  .then(function(jane) { created.jane = jane; return User.create({ username: 'Pete' }) })
  .then(function(pete) {
    created.pete = pete;

    console.log("we just created 3 users :)")
    console.log("this is pete:")
    console.log(created.pete.values)

    // what i want:
    console.log("this is jane:")
    console.log(created.jane.values)

    console.log("this is john:")
    console.log(created.john.values)
  })

不过,总的来说,我建议您倾向于 @Bergi 的回答,它会创建一个 Promises 列表并等待所有 Promise 完成。

根据问题更新进行编辑:

使用更新后的代码块并基于@Bergi 对Promise.map 的建议,您可以避免在更高范围内使用变量,如下所示:

User.hasMany(Group)
Group.hasMany(User)

User
  .sync({ force: true })
  .then(function() {
    var users = Promise.map( ['John', 'Jane', 'Pete'], function(name) {
      return User.create({ username: name });
    });
    var group = Group.findOrCreate({id: 1});
    return Promise.all([group, users]);
  })
  .spread(function(group, users) {return group.setUsers(users)})
  .then(function(result) { console.log(result)})
})

【讨论】:

  • 谢谢。我为我的问题添加了更新。看起来你的代码示例很适合我的任务
  • 你已经得到了Promise.all 一半的权利:-) users 确实已经有Promise<[User]> 的类型,group 确实有Promise<Group> 的类型,现在我们想要获取Promise<(Group, [User])> - 等待创建所有用户并找到组...
  • 我阅读了Promise.spread 的文档,发现它保证了对Promise.all 的调用。这就是为什么我相信我不需要 Promise.all 来包装返回的数组。我找不到Promise.map 的文档,所以我不知道它会给我一个Promise<[User]> 而不是[Promise<User>]。这就是为什么我的评论存在于Promise.all 包装用户数组的必要性。我忘了检查Promise.all 是否会递归到它找到的数组中(如[<Promise<x>|[Promise<y>]>])。
【解决方案3】:

试试这个...

User
    .sync({ force: true })
    .then(function () {
        return User.create({ username: 'John' });
    })
    .then(function (john) {
        console.log("this is john:");
        console.log(john.values);
        return User.create({ username: 'Jane' });
    })
    .then(function (jane) {
        console.log("this is jane:");
        console.log(jane.values);
        return User.create({ username: 'Pete' });
    })
    .then(function (pete) {
        console.log("we just created 3 users :)");
        console.log("this is pete:");
        console.log(pete.values);
    });

【讨论】:

  • 这可能是我能找到的唯一一个体面但简单的续集承诺示例。谢谢。
猜你喜欢
  • 2019-03-27
  • 2021-12-28
  • 2021-01-13
  • 2015-07-15
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
相关资源
最近更新 更多