node.js - 输出不正确,需要同步for循环
问题描述
exports.calculateGstBaseOnInput = function(req, res) {
console.log("welcome");
for (var item of req.body.so_items) {
req.productid = item.productid;
req.qty = item.qty;
getItemDetail(req, res).then(function(result) {
return getCartItems(req, res);
}).then(function(result) {
return calculateGST(req, res);
})
}
}
getItemDetail = function(req, res) {
return new Promise(function(resolve, reject) {
console.log("inside getItemDetail");
var SQL = "mysql query";
mysqlConnect.query(SQL, function(err, result, fields) {
if (err) {
console.log("inside err");
res.json({ status: 'Failure', statusMessage: 'item does not exist' });
} else if (result.length < 0) {
console.log("inside length 0");
res.json({ status: 'Failure', statusMessage: 'item does not exist' });
} else {
req.itemdetail = result;
console.log("price inside getitemdetail= ", req.itemdetail[0].price);
//callback();
}
});
resolve('done');
});
}
getCartItems = function(req, res) {
return new Promise(function(resolve, reject) {
console.log("inside getCartItems");
var SQL = "mysql query";
mysqlConnect.query(SQL, function(err, result, fields) {
if (err) {
res.json({ status: 'Failure', statusMessage: 'item does not exist' });
} else if (result.length < 0) {
res.json({ status: 'Failure', statusMessage: 'item does not exist' });
} else {
req.cartItems = result;
//callback();
}
});
resolve('done');
});
}
calculateGST = function(req, res) {
return new Promise(function(resolve, reject) {
console.log("inside calculateGST");
if (req.userDetails[0].is_gst_included) {
//total = req.qty * req.itemdetail[0].price;
// console.log("price = ",req.itemdetail[0].price);
//callback();
} else {
//total = req.qty * req.itemdetail[0].price;
//console.log("price = ",req.itemdetail[0].price);
//total = req.qty * req.itemdetail[0].price;
}
resolve('done');
});
}
实际输出:
inside getItemDetail
inside getItemDetail
inside getCartItems
inside getCartItems
inside calculateGST
inside calculateGST
预期输出(我想要的输出):
inside getItemDetail
inside getCartItems
inside calculateGST
inside getItemDetail
inside getCartItems
inside calculateGST
我如何在不设置任何时间的情况下实现这一目标。
解决方案
您正在resolve
ing 立即执行,而不是在提供给mysqlConnect.query()
.
考虑您的getItemDetail
函数的缩写版本:
function getItemDetail(req, res) {
return new Promise(function(resolve, reject) {
var SQL = "mysql query";
mysqlConnect.query(SQL, function(err, result, fields) {
// Stuff
});
resolve('done');
});
}
它的逻辑是:
- 创造一个新的承诺
- 开始一个
query
resolve()
- 无论叫
getItemDetail
什么都应该做,因为getItemDetail
解决了 query
稍后完成
相反,您可能应该做这样的事情,在resolve
回调中的query
位置:
function getItemDetail(req, res) {
return new Promise(function(resolve, reject) {
var SQL = "mysql query";
mysqlConnect.query(SQL, function(err, result, fields) {
// Stuff
resolve('done');
});
});
}
这里的逻辑是:
- 创造一个新的承诺
- 开始一个
query
getItemDetail
调用者不应该做任何事情,因为getItemDetail
还没有解决query
在某个时候完成并触发回调resolve
getItemDetail
调用者现在将继续,因为它已被告知该函数已解决
您需要在调用方继续之前需要实际完成查询的任何函数中遵循此模式。
您还应该考虑利用async/await
. 考虑使用您的代码作为基础的这个简短示例:
const mysqlConnect = {
query(sql, cb) {
setTimeout(() => {
cb(null, ["foo"], ["bar"]);
});
}
};
(async function() {
const t = await calculateGstBaseOnInput({
body: {
so_items: ["a", "b", "c"]
}
});
}());
async function calculateGstBaseOnInput(req, res) {
for (var item of req.body.so_items) {
const itemDetail = await getItemDetail(req, res);
const cartItems = await getCartItems(req, res);
const gst = await calculateGST(req, res);
}
}
function getItemDetail(req, res) {
console.log("getItemDetail");
return new Promise(function(resolve, reject) {
var SQL = "mysql query";
mysqlConnect.query(SQL, function(err, result, fields) {
// Stuff
resolve('done');
});
});
}
function getCartItems(req, res) {
return new Promise(function(resolve, reject) {
console.log("---getCartItems");
var SQL = "mysql query";
mysqlConnect.query(SQL, function(err, result, fields) {
// Stuff
resolve('done');
});
});
}
function calculateGST(req, res) {
return new Promise(function(resolve, reject) {
console.log("------calculateGST");
// Stuff
resolve('done');
});
}
这输出:
getItemDetail
---getCartItems
------calculateGST
getItemDetail
---getCartItems
------calculateGST
getItemDetail
---getCartItems
------calculateGST
推荐阅读
- nativescript - CLI 更新后 Nativescript Sidekick 不会启动
- python - 如何为 tkinter 中的每个按钮状态设置个人图片?
- c++ - 如何从 QT C++ 中的对话框向父主窗口发送密钥
- php - symfony 上的单元测试问题
- c - clang 中是否有固定宽度的浮点类型?
- javascript - 同一服务的零星 400(错误请求)
- java - 将 JSF/CDI 依赖注入到 ActionListener
- tensorflow - Windows 10,CUDA 9,: ..\src\THC\THCG 处的 CUDA 运行时版本的 CUDA 驱动程序版本不足
- php - Instagram API 端点
- sql - 如何检查空值的连接值并在其他表中查找