1

New to async and struggling. As an example below I wish to init a table then process it's contents by: a) Remove old data b) Insert a new record c) Read the table into an array d) Display the array

'use strict';


// ================================================================================
// Module dependencies
var pgp      = require('pg-promise')();


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


// ================================================================================
// Initialise rhe variables
var customers = [];


// ================================================================================
// Initialise table
db.none("DELETE FROM testing")
  .then(function(data) {
    console.log("Deleted old records");
    // success;
  })
  .catch(function(error) {
    console.log(error);
  });

db.none("INSERT INTO testing (firstname, surname) VALUES ('Bob', 'Brown')")
  .then(function(data) {
    console.log("Inserted new record");
    // success;
  })
  .catch(function(error) {
    console.log(error);
  });


// ================================================================================
// Display records
db.any("SELECT * FROM testing")
  .then(function(data) {
    console.log("Looping records");
    data.forEach(function(row, index, data) {
      customers.push(row.firstname, row.lastname);
      console.log(row);
    });
  })
  .catch(function(error) {
    console.log(error);
  });

console.log("The customers are:");
console.log(customers);

The output is not as desired but somewhat as expected. Interestingly after "Inserted new records" there is a 30 second wait before the command prompt is retuned.

The customers are:
[]
Looping records
anonymous {
  id: 3,
  firstname: 'Bob',
  surname: 'Brown',
  created: 2016-08-03T01:43:34.880Z }
Deleted old records
Inserted new record

My question is ultimately with async programming surely there are scenarios where actions need to be performed in sequence such as the example above and in such a scenario how can this be coded in an async environment such as node.js.

4

2 回答 2

2

由于您使用的是支持承诺访问数据库的库,因此您应该在下一个.then方法中执行每个步骤。如果您不执行.then方法中的步骤,则每个语句都会在当前“tick”上执行,直到没有更多针对该“tick”的语句。异步方法(调用 withdb.none(...)将在未来的“滴答声”上执行。这是您将最后 2 个console.log语句视为第一个输出的方式。

尝试将您的代码更改为以下内容以获得更好的工作流程:

'use strict';


// ================================================================================
// Module dependencies
var pgp      = require('pg-promise')();


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


// ================================================================================
// Initialise rhe variables
var customers = [];


// ================================================================================
// Initialise table
db.none("DELETE FROM testing")
  .then(function(data) {
    console.log("Deleted old records");
    // success;

    return db.none("INSERT INTO testing (firstname, surname) VALUES ('Bob', 'Brown')");
  })
  .then(function(data) {
    console.log("Inserted new record");
    // success;

    // Display records
    return db.any("SELECT * FROM testing");
  })
  .then(function(data) {
    console.log("Looping records");
    data.forEach(function(row, index, data) {
      customers.push(row.firstname, row.lastname);
      console.log(row);
    });
  })
  .then(function() {
    console.log("The customers are:");
    console.log(customers);
  })
  .catch(function(error) {
    console.log(error);
  });

查看每个动作/步骤在另一种.then方法中的表现。此外,由于db.方法返回 Promise,您可以在.then方法中返回它们,并且 next.then将在该语句完成时执行。

希望这可以帮助。

于 2016-08-03T02:54:06.433 回答
1

解决方案将取决于查询之间是否存在依赖关系。如果他们是依赖的,你会像承诺的那样把他们锁起来;否则,您可以将它们作为批处理并行执行:

'use strict';

var promise = require('bluebird');

var pgp = require('pg-promise')({
    promiseLib: promise // use a custom promise library
});

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

var db = pgp(config);

function prepareCustomers(t) {
    return t.batch([
        t.none('DELETE FROM testing'),
        t.none('INSERT INTO testing VALUES($1, $2)', ['Bob', 'Brown']),
        t.any('SELECT * FROM testing')
    ])
        .then(data=>data[2]); // get results from the select query
}

db.tx(prepareCustomers)
    .then(customers=> {
        console.log(customers);
    })
    .catch(error=> {
        console.log(error);
    })
    .finally(pgp.end); // only call pgp.end when exiting the application

此外,当您像这样在数据库中进行更改时,您通常会为此使用事务,如上面的示例所示。

有趣的是,在“插入新记录”之后,需要等待 30 秒才能重新调整命令提示符。

请参阅库反初始化

于 2016-08-05T15:54:34.990 回答