8

我是来自同步编程背景的 node.js 和 pg-promise 的新手,它需要新的思维。

我将从在主程序逻辑之前运行数据库初始化的场景开始。

按照这个例子: https ://github.com/vitaly-t/pg-promise/wiki/Learn-by-Example#simple-select

db.any("select * from users where active=$1", [true])
  .then(function (data) {
    // success;
  })
  .catch(function (error) {
    // error;
  });

我的代码是否会读作:

db.query("DELETE FROM records")
  .then(function (data) {
    // success;
    console.log("This is where all my main logic goes");
  })
  .catch(function (error) {
    // error;
  });

或者它会读作:

db.query("DELETE FROM records")
  .then(function (data) {
    // success;
  })
  .catch(function (error) {
    // error;
  });
console.log("This is where all my main logic goes");

我的理解是,对于后者,消息将在记录被删除之前显示。

更新: 在阅读了许多关于承诺和回调的文章后,我了解到 pg-promise 使用 .then 和 .catch 链接成功和错误场景。我现在也相信我理解 pg-promise 命令应该放在函数包装器中,例如:

function initialiseDB() {
  db.query("DELETE FROM records")
    .then(function (data) {
      // success;
    })
    .catch(function (error) {
      // error;
    });
  }

然后在我的代码中,我将使用一个简单的命令调用该函数,该命令将异步运行该函数:

initialiseDB();

然而,我仍然不确定这种异步编码和承诺的概念如何适合程序的整体结构,因为可以肯定,程序中的几乎所有内容都需要首先完成初始化。因此,整个程序是否不需要放在函数的“.then”部分?即顶层的唯一代码实际上是 intialiseDB() 函数?

// Start of code here 
var pgp = require('pg-promise')();

//Configure the database connection
var config = {
  user:               'username', //env var: PGUSER 
  database:           'database', //env var: PGDATABASE 
  password:           'password', //env var: PGPASSWORD 
};

var db = pgp(config);

function initialiseDB() {
  db.query("DELETE FROM records")
    .then(function (data) {
      // This is where the main program logic goes after this line;
    })
    .catch(function (error) {
      // error;
    });
}

// Commence the program here
initialiseDB();
4

1 回答 1

3

PG promise 实际上允许在较新的 nodejs 版本上使用generators和使用。需要一个具有重要内置到系统中的承诺的适配器,因此提供一个将允许以同步方式更清晰的代码流async/awaitGeneratorsgenerator function

取自标签任务下的存储库

没有generators

db.task(t => {
        // this.ctx = task config + state context;
        return t.one('SELECT * FROM users WHERE id = $1', 123)
            .then(user => {
                return t.any('SELECT * FROM events WHERE login = $1',user.name);
            });
    })
    .then(events => {
        // success;
    })
    .catch(error => {
        // error;
    });

generators

db.task(function * (t) {
        // this.ctx = task config + state context;
        let user = yield t.one('SELECT * FROM users WHERE id = $1', 123);
        return yield t.any('SELECT * FROM events WHERE login = $1', user.name);
    })
    .then(events => {
        // success;
    })
    .catch(error => {
        // error
    });

如果使用async/await,您可以简单地替换function * (t)withasync function (t)yieldwith await,它的工作原理大致相同。

一些警告:

在更复杂的逻辑中,您应该在可能失败的事情周围使用 try catch 块,因为它们会将错误冒泡generators并且async/await

db.task(function * (t) {
    yield Promise.reject(new Error('This will cause your app to error')
}

您还应该密切关注他的 pg-promise 演示!它会教你一些很棒的东西,比如扩展事件、repos、外部 SQL 文件,以及库中的很多其他很棒的东西,比如助手!

于 2017-09-14T18:00:24.303 回答