我正在嘗試做兩件事:
- 從資料庫中獲取唯一的 conversationId 串列
- 獲取每個對話的最新訊息
但是,我無法使用回傳的訊息遍歷陣列。我已經嘗試在單獨的函式中將代碼的 2 部分分開。從另一個呼叫一個,現在用 .then 陳述句按順序呼叫它們,但沒有任何效果。我真的很感激一些幫助......
這是 NodeJS,帶有 SQLite3
這是控制臺顯示正在回傳的內容:

這是獲取訊息的代碼:
function getConversationsList(idList)
{
var c = [];
return new Promise((resolve) => {
idList.forEach((id => {
db.all("SELECT * FROM messages WHERE (conversationId = ? AND isBroadcast = 0 AND isWarmup = 0) ORDER BY messageTime DESC LIMIT 1",{1:id},function(err,row) {
if(err)
{
console.log(err.message);
return resolve(err);
}
row.forEach((d => {
console.log(d);
c.push(d);
}))
});
}))
resolve(c);
});
}
function convoidlist()
{
idlist = [];
return new Promise((resolve) => {
db.all("SELECT DISTINCT conversationId FROM messages",{},function(err,rows){
if(err)
{
console.log(err)
}
rows.forEach((row) => {
idlist.push(row.conversationId);
});
resolve(idlist);
})
});
}
這是試圖回圈它們的代碼,沒有錯誤,但回圈永遠不會進入......
function refreshConversations()
{
convoidlist().then((idlist) => {
getConversationsList(idlist).then((f) => {
console.info(f);
var chtml = "";
f.forEach((e,index,array) => {
console.info(e[index]);
var newc = `
<div data-id="${e.conversationId}" style="width:100%;padding:10px;margin-bottom:20px;" class="border">
<div width="100%" style="font-size:0.8em;"><span style="width:50%;text-align:left">${e.messageFrom}</span><span style="width:40%;">${e.messageTime}</span></div>
<div width="100%" style="height:100px;overflow:hidden;">${e.messageBody}</div>
</div>
`;
chtml = chtml newc;
console.log(newc);
});
console.log(chtml);
document.getElementById('conversationlist').innerHTML = chtml;
});
});
}
我知道它有點亂,它更清晰,但我已經嘗試了很多。任何幫助表示贊賞。
uj5u.com熱心網友回復:
您正在混合承諾、常規異步回呼,.forEach()這確實使撰寫適當的異步代碼變得困難。最好先承諾任何異步操作。
如果您無法訪問支持承諾的 sqlite3 版本,那么您可以承諾您需要使用的特定操作(就像我在這里所做的那樣)。這會更好地集中在一個地方進行,但是由于您沒有顯示該級別的代碼背景關系,因此我只是在這個特定問題中在本地進行。
然后,避免.forEach()在回圈中使用異步操作,因為.forEach()它不是承諾感知或異步感知的。它只是愉快地運行它的回圈,而無需等待任何異步操作完成,這很難管理。
這是一種承諾和重組的做事方式:
const { promisify } = require("util");
async function getConversationsList(idList) {
// promisify db.all
db.allP = promisify(db.all);
const data = [];
for (let id of idList) {
const rows = await db.allP("SELECT * FROM messages WHERE (conversationId = ? AND isBroadcast = 0 AND isWarmup = 0) ORDER BY messageTime DESC LIMIT 1", { 1: id });
data.push(...rows);
}
return data;
}
async function convoidlist() {
db.allP = promisify(db.all);
const rows = await db.allP("SELECT DISTINCT conversationId FROM messages", {});
return rows.map(row => row.conversationId);
}
async function refreshConversations() {
try {
const idlist = await convoidlist();
const conversations = await getConversationsList(idlist);
console.info(conversations);
let html = conversations.map(e => {
return `
<div data-id="${e.conversationId}" style="width:100%;padding:10px;margin-bottom:20px;" >
<div width="100%" style="font-size:0.8em;"><span style="width:50%;text-align:left">${e.messageFrom}</span><span style="width:40%;">${e.messageTime}</span></div>
<div width="100%" style="height:100px;overflow:hidden;">${e.messageBody}</div>
</div>
`
});
document.getElementById('conversationlist').innerHTML = html.join("/n");
} catch (e) {
console.log(e);
// decide what to show the user here if there was an error
}
}
筆記:
- 添加
db.allP()為db.all(). - 僅對異步控制流使用 Promise。
- 擺脫
.forEach()回圈中異步操作的任何使用。僅使用 Promise 和for使用await. - 在
refreshConversations()中,您呼叫convoidlist(),但從不使用其結果。 - 將錯誤報告集中在
refreshConversations(). 低級函式應該回傳資料或錯誤。更高級別的函式決定如何處理錯誤以及何時記錄它們。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/511663.html
下一篇:驗證Sqlite表中是否存在索引
