异步和挣扎的新手。作为下面的示例,我希望初始化一个表,然后通过以下方式处理它的内容: a)删除旧数据 b)插入新记录 c)将表读入数组 d)显示数组
'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);
输出不是预期的,但有点像预期的那样。有趣的是,在“插入新记录”之后,在命令提示符重新调整之前有30秒的等待时间。
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
我的问题最终是异步编程肯定存在需要按顺序执行操作的情况,例如上面的示例,在这种情况下,如何在异步环境(如node.js)中编码。
答案 0 :(得分:2)
由于您使用的是支持promises访问数据库的库,因此您应该在下一个.then
方法中执行每个步骤。如果不执行.then
方法中的步骤,则每个语句都在当前“tick”上执行,直到没有更多语句为“tick”。异步方法(使用db.none(...)
调用)将在未来的“tick”上执行。这样您就可以看到最后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.
方法返回promises,您可以返回.then
方法中的那些方法,并且当该语句结束时将执行下一个.then
。
希望这有帮助。
答案 1 :(得分: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秒的等待时间。