javascript - Sails.js 使用带有 promise 的事务的最佳实践(Postgres)

标签 javascript node.js sails.js waterline

我正在使用带有 Postgres 的 Sails 0.9.16,我的问题是:使用当前 API 和 Promise 执行事务的最佳方式是什么?可能有比以下更好的东西:

    Model.query('BEGIN TRANSACTION', function (err) {
      if (err) {
        next(err);
      } else {
        Model
          .create(...)
          .(function (value) {
            return [value, RelatedModel.create(...).then(...)];
          })
          .fail(function (err) {
            Model.query('ROLLBACK');
            next(err);
          })
          .spread(function (...) {
            Model.query('COMMIT')
            next(...);
          })
      }
    })

感谢您的帮助!

最佳答案

我目前正在使用这个确切的工作流程。要使用 Promise 执行一个查询,请执行以下操作:

Model
 .query(params)
 .then(function(result){
 //act on result
 })
 .catch(function(error){
 //handle error
 })
 .done(function(){
 //clean up
 });

要并行执行多个查询,请执行以下操作:

var Promise = require('q');

Promise.all([

    User.findOne(),
    AnotherModel.findOne(),
    AnotherModel2.find()

])
.spread(function(user,anotherModel,anotherModel2){
    //use the results
})
.catch(function(){
    //handle errors
})
.done(function(){
    //clean up
});

如果您想避免在代码中嵌套:

Model
.query(params)
.then(function(result){//after query #1
    //since you're returning a promise here, you can use .then after this
    return Model.query();
})
.then(function(results){//after query#2
    if(!results){
        throw new Error("No results found in query #2");
    }else{
        return Model.differentQuery(results);
    }

})
.then(function(results){
//do something with the results
})
.catch(function(err){
    console.log(err);
})
.done(function(){
    //cleanup
});

注意:目前,waterline 使用 Q 表示 promise。这里有一个将水线从 Q 切换到 bluebird 的拉取请求:waterline/bluebird

当我回答这个问题时,我还没有上大学的数据库课,所以我不知道什么是事务。我做了一些挖掘工作,bluebird 允许您使用 promise 进行交易。唯一的问题是,这并没有完全内置在风 sails 中,因为它是一个特殊的用例。这是 bluebird 针对这种情况提供的代码。

var pg = require('pg');
var Promise = require('bluebird');
Promise.promisifyAll(pg);

function getTransaction(connectionString) {
    var close;
    return pg.connectAsync(connectionString).spread(function(client, done) {
        close = done;
        return client.queryAsync('BEGIN').then(function () {
            return client;
        });
    }).disposer(function(client, promise) {
        if (promise.isFulfilled()) {
            return client.queryAsync('COMMIT').then(closeClient);
        } else {
            return client.queryAsync('ROLLBACK').then(closeClient);
        }
        function closeClient() {
            if (close) close(client);
        }
    });
}

exports.getTransaction = getTransaction;

关于javascript - Sails.js 使用带有 promise 的事务的最佳实践(Postgres),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24691385/

相关文章:

javascript - Node js如何等待所有url完成并抛出成功消息?

json - 如何从 Node 流式传输 JSON?

node.js - 在 SailsJS 中维护模型更新历史

javascript - 区域.js : 140 Uncaught TypeError: Cannot read property 'remove'

node.js - Express 中间件 : allow access to only admin or moderator

javascript - 使用 Javascript 的选定单词的索引

javascript - 连接失败时 Node js TLS 未捕获错误?怎么抓?

sails.js - Sails Waterline Sync 调用

javascript - .hover 不适用于我动态分配类的元素

javascript - 多复选框渲染