我正在使用while回圈遍歷一個陣列并嘗試使用return終止回圈(我之前嘗試過foreach,它不會終止return,但while回圈應該使用return終止)。
有人可以幫我為什么會這樣嗎?
這是我的代碼:
req.on("data", async data => {
let fetchedData = JSON.parse(data.toString())
let index=0
while(index<fetchedData.length) {
const invoice = fetchedData[index]
// fetchedData.forEach((invoice, index) => {
console.log('index',index)
await new Promise((resolve, reject) => {
db.query(
`SELECT * FROM payments WHERE invoice_id = '${invoice.id}' and status = 1`,
(err, results) => {
if (err) {
resolve()
return res.json({
status: "error",
message: "something went wrong!",
})
} else {
if (results.length > 0) {
resolve()
console.log('returned')
return res.json({
status: "error",
message: `Payment is already done for invoice number ${invoice.invoiceNumber} ! Please delete the payment first.`,
})
} else if (index == fetchedData.length - 1) {
for(let i =0; i<fetchedData.length; i ){
db.query(`UPDATE invoices SET status = 0 WHERE id = '${fetchedData[i].id}'`, (err, results) => {
if (err) {
resolve()
return res.json({
status: "error",
message: "something went wrong!",
})
} else{
deletedInvoices.push(fetchedData[i].id)
if(i == fetchedData.length - 1){
console.log('deleted')
return res.json({
status: "success",
message: "invoice deleted",
deletedInvoices: deletedInvoices
})
}
resolve()
}
})
}
}
}
}
)
})
index ;
}
})
輸出:對于長度為 2 的陣列:
索引 0
回來
索引 1
回來
(它也會拋出一個錯誤,因為它發送了兩次回應!
uj5u.com熱心網友回復:
簡而言之:該return陳述句適用于它所在的函式的范圍。并且您的回圈位于外部范圍內。
可能的解決方案
您可以在while回圈的同一范圍內定義另一個變數,在每次迭代中檢查它,當您希望內部范圍結束回圈時,您不僅回傳而且設定該變數。
就像是:
// ...
let index=0
let shouldLoopContinue = true
while(shouldLoopContinue && index<fetchedData.length) {
// ...
和:
// ...
if (err) {
resolve()
shouldLoopContinue = false
return res.json({
status: "error",
message: "something went wrong!",
})
}
// ...
以及在任何其他回傳并應該停止回圈的地方。
解釋
在你的情況下:
- 您呼叫的范圍
return是作為引數傳遞給db.query(...). db.query(...)本身在傳遞給的回呼函式的范圍內new Promise(...)while...與您的回圈在同一范圍內
因此,當您return以現在的方式呼叫時,您只會結束該內部回呼的執行。
uj5u.com熱心網友回復:
您的return陳述句不是回呼中while回圈的req.on一部分,而是dq.query回呼函式的一部分。所以它們與回圈無關。
一種方法是對功能進行承諾db.query。檢查您的資料庫 API 的檔案,因為此方法可能已經有一個回傳承諾的替代方案。但如果沒有,您可以改用這個通用函式:
const asyncQuery = (db, sql) =>
new Promise((resolve, reject) =>
db.query(sql, (err, results) =>
err ? reject(err) : resolve(results)
)
);
現在您可以將這些return陳述句直接放入回圈中,它們將退出db.req回呼:
req.on("data", async data => {
try {
const fetchedData = JSON.parse(data.toString())
for (const {id, invoiceNumber} of fetchedData) { // Simpler loop
const results = await asyncQuery(db, `SELECT * FROM payments WHERE invoice_id = '${id}' and status = 1`)
if (results.length > 0) {
// Now we are in the req.on callback, so this will exit it:
return res.json({
status: "error",
message: `Payment is already done for invoice number ${invoiceNumber} ! Please delete the payment first.`,
});
}
}
for (const {id} of fetchedData) {
await asyncQuery(db, `UPDATE invoices SET status = 0 WHERE id = '${id}'`);
}
res.json({
status: "success",
message: "invoice deleted",
deletedInvoices: fetchedData.map(({id}) => id)
});
} catch (err) {
res.json({
status: "error",
message: "something went wrong!",
});
}
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/474076.html
標籤:javascript 节点.js 循环 while循环
下一篇:將變數從前端傳遞到后端
