节点.js处理异步
Node.js Dealing with Async
我试图了解node.js的异步性质。我有一条快速路线,我知道它下面不会提供我需要的数据。从本质上讲,第一个 mysql 查询按预期 100% 工作,并且在 res.json 中返回的 json 数据是正确的。然而,在第一个mysql函数中,我调用另一个函数"getOrderLines()",它总是返回'{"Item":[]}'而不是我期望的数据。
我知道这是因为节点的异步性质而发生这种情况,但是我似乎无法解决这个问题,我已经研究了承诺并编写了一些基本承诺,但无法让它适用于以下内容。
任何帮助将不胜感激。
router.route('/salesOrders')
.get(function (req, res) {
mysql.query("QUERY", function (err, sql1) {
for (i = 0; i < sql1.length; i++) {
json.Company.SalesOrders.SalesOrder[i] = {
"Id": sql1[i].Id,
"AccountReference": sql1[i].AccountReference,
"SalesOrderDate": sql1[i].SalesOrderDate,
"SalesOrderAddress": [{
"Forename": sql1[i].billFirstname,
"Lastname": sql1[i].billLastName,
"Address": sql1[i].billAddress1
}],
"SalesOrderItems": {}
};
json.Company.SalesOrders.SalesOrder[i].SalesOrderItems = getOrderLines(sql1[i].Id);
} // End first For loop.
res.json(json);
};
};
getOrderLines = function (orderId) {
var orderLineJson = {
"Item": []
};
mysql.query('QUERY', function (err, sql2) {
for (j = 0; j < sql2.length; j++) {
orderLineJson.Item[j] = {
"SKU": sql2[j].name,
"QtyOrdered": sql2[j].quantity,
"UnitPrice": sql2[j].price
};
}
});
return orderLineJson;
};
处理异步操作时不能使用 return
。我建议学习和实践承诺。起初它们有点难以理解,但一旦点击,我想你会更喜欢它们继续通过,你可以从那里开始。
现在,您需要学习使用回调。承诺仍然使用回调。将回调传递给异步函数,并在异步操作完成后调用它:
function getOrderLines(orderId, cb) {
mysql.query('QUERY', function (err, sql2) {
// handle err
cb(/* processed data */)
});
}
当您调用 getOrderLines
时,您将该回调传入,这允许您使用传递给它的值:
getOrderLines(sql1[i].Id, function (err, result) {
res.json(result);
});
getOrderLines是一个异步任务,调用这种方式将返回空数组
..SalesOrderItems = getOrderLines(sql1[i].Id);
使用异步模块
var async = require('async');
router.get('/salesOrders', function(req, res) {
// your object here
var json = {
Company:{
SalesOrders: {
SalesOrder: []
}
}
};
var getSalesOrder = function(callback){
mysql.query("QUERY", function(err, sql1) {
for (var i = 0; i < sql1.length; i++) {
// push item into array
json.Company.SalesOrders.SalesOrder.push({
"Id": sql1[i].Id,
"AccountReference": sql1[i].AccountReference,
"SalesOrderDate": sql1[i].SalesOrderDate,
"SalesOrderAddress": [{
"Forename": sql1[i].billFirstname,
"Lastname": sql1[i].billLastName,
"Address": sql1[i].billAddress1
}],
"SalesOrderItems": {}
});
}
// job done, trigger next function;
callback();
});
}
var getOrderLines = function(callback) {
var orderLineJson = {"Item":[]};
var dataLength = json.Company.SalesOrders.SalesOrder.length;
for(var i=0; i<dataLength; i++){
// do what ever you like with orderId
var orderId = json.Company.SalesOrders.SalesOrder[i].Id;
// async query
mysql.query('QUERY', function(err, sql2) {
for (var j = 0; j < sql2.length; j++) {
orderLineJson.Item.push({
"SKU": sql2[j].name,
"QtyOrdered": sql2[j].quantity,
"UnitPrice": sql2[j].price
});
}
json.Company.SalesOrders.SalesOrder[i].SalesOrderItems = orderLineJson;
// check for the last item
if(i == dataLength-1)
callback();
});
}
}
// run async sequentially
async.series([getSalesOrder, getOrderLines], function(err, result){
// finally send the json
res.json(json);
});
});
相关文章:
- 异步处理所有事件处理程序的方法
- 如何异步处理:函数C取决于函数B取决于函数A
- 如何处理异步获取的数据
- Javascript/JQuery处理并发/异步调用和数据竞争
- 使用异步模块的Express + Mongoose请求处理程序的更简洁的方法
- 直接 Web 远程处理异步问题
- ExtJs 处理异步调用
- 处理异步函数
- 使用Canvas和ForEach处理异步调用
- 处理角控制器中异步更新的正确方法
- 如何在angular.js中处理多个异步任务
- 处理函数中的异步调用(Firebase)
- 节点 JS Express 模块是否异步处理请求
- 异步处理不影响 React+Flux 中视图的数据
- 使用一个小模型来测试异步处理
- 在Node.js中异步处理数组
- 如何在异步处理过程中解析对象
- 使用javascript异步处理多个XMLHTTP请求
- 串行地处理异步处理的消息队列
- 当所有异步处理程序完成时执行javascript函数