我在理解nodejs上的异步方法时遇到问题。
我的控制器中有这段代码片段:
app.get(basePath, function (req, res, next) {
model.generateDB(function (modelErr, modelRes) {
if (modelErr) console.log('Error: ' + modelErr);
next(res.send(modelRes));
});
});
该模型的代码片段:
generateDB: function (next) {
BDManager.query(
'INSERT INTO tableName' +
'(field1, field2) VALUES ("a", "b")',
function (err, res) {
next(err, res);
});
}
以及数据库管理器的这段代码
query: function (sql, next) {
var con = mysql.createConnection(config.MySQL);
con.query(sql, function (err, res) {
if (err) next(err, null);
next(null, res);
});
con.end();
}
对我来说很好。问题是,如何仅通过一个控制器调用就可以在模型中对多个响应进行响应,例如示例(不起作用):
BDManager.query(
'INSERT INTO tableName' +
'(field1, field2) VALUES ("a", "b")',
function (err, res) {
next(err, res);
});
BDManager.query(
'INSERT INTO tableName' +
'(field1, field2) VALUES ("a", "b")',
function (err, res) {
next(err, res);
});
BDManager.query(
'INSERT INTO tableName' +
'(field1, field2) VALUES ("a", "b")',
function (err, res) {
next(err, res);
});
这个想法可能是获得一系列错误和响应,但是我不知道如何在所有查询结束后发送它。我尝试使用.then,但似乎不起作用(我使用.then时遇到的错误是“无法使用null时使用”)。
另一种解决方案是将多个查询合并在一起,但是我尝试使用“;”分隔符,但对我不起作用。
答案 0 :(得分:1)
因此,这使用了回调(.then用于保证)。您可以在其周围创建一个Promise包装器,以使其承诺化,然后等待它们或使用promise.All,如果您想并行运行它们。
例如:
function promiseQuery(query, params) {
return new Promise((resolve, reject) => {
BDManager.query(query, params, function (err, res) {
if (err) return reject(err);
return resolve(res);
});
});
}
let arrayOfResponses = await Promise.all([
promiseQuery(query1, params1),
promiseQuery(query2, params2),
promiseQuery(query3, params3),
]);
关于此的几件事-您可能应该通过参数化的输入插入值。您的SQL库应该应支持
错误也会对此产生拒绝。如果您想捕获这些错误并将其推送到数组,也可以使用.catch处理程序来做到这一点。
如果您不使用异步/等待或兼容版本的节点,也可以执行以下操作:
Promise.all([]).then(arrayOfResponses => {});
同样,这将为您传递给promise.all的所有诺言提供一系列响应。
关于如何使用Promises及其如何工作的文章很多,但这应该可以帮助您入门。