[英]Nodejs appears to return a response before waiting for functions containing Promises to resolve
我正在嘗試點擊我的 API 端點“類別”以從 firebase 中的類別集合返回文檔列表。 使用以下代碼:
function getCategories() {
let arr = [];
categories
.get()
.then(snapshot => {
snapshot.forEach(doc => {
console.log(doc.data().category);
arr.push(doc.data().category);
return arr;
});
})
.catch(err => {
console.log(err);
return [1, 2, 3];
});
}
router.route("/categories").get(async function(req, res, next) {
let arr = await getCategories();
res.json(arr);
});
雖然我沒有收到任何錯誤,但我收到一個空響應,在調試時顯示arr
未定義。 問題是當使用調試器時, forEach
的控制台日志被調用,我在控制台中看到了我的類別,但由於某種原因,它不會等待 Firebase Promise 解析,路由器只是用未定義的arr
變量進行響應。
您的.then
回調應該更像這樣(不需要單獨的arr
變量):
function getCategories() {
// notice we are returning the promise
return categories
.get()
.then(snapshot => {
// notice we are returning the new array using .map()
return snapshot.map(doc => {
console.log(doc.data().category);
return doc.data().category;
});
})
.catch(err => {
console.log(err);
return [1, 2, 3];
});
}
並且由於您已經在使用 async/await,您可以將所有內容重寫為如下所示,以便您的用戶可以知道何時發生錯誤:
// notice the function is now async
async function getCategories() {
const snapshot = await categories.get()
// this can be a one-liner in the example above too
return snapshot.map(doc => doc.data().category);
}
router.route("/categories").get(async function(req, res, next) {
try {
let arr = await getCategories();
res.json(arr);
} catch(ex) {
res.status(500).json({ msg: ex.message });
}
});
您不會在.then
返回您的承諾和價值。 在categories.get()
調用前添加return
並在其中返回值。
如果你想在它上面使用await
, getCategories
需要返回一個 promise。 現在,它什么也沒有返回。 您需要返回您創建的承諾:
function getCategories() {
let arr = [];
return categories
.get()
.then(snapshot => {
snapshot.forEach(doc => {
console.log(doc.data().category);
arr.push(doc.data().category);
return arr;
});
})
.catch(err => {
console.log(err);
return [1, 2, 3];
});
}
請注意return
關鍵字。
您也可能在這里遇到另一個問題。 您正在使用forEach
迭代快照,並從傳遞給forEach
的 lambda 函數中返回arr
。 這不會將快照數據返回給調用者。 您將需要從返回一個值, then
拉姆達:
.then(snapshot => {
const arr = []
snapshot.forEach(doc => {
console.log(doc.data().category);
arr.push(doc.data().category);
});
return arr;
})
你可以嘗試這樣的事情:
function getCategories() {
let arr = [];
categories
.get()
.then(snapshot => {
snapshot.forEach(doc => {
console.log(doc.data().category);
arr.push(doc.data().category);
});
console.log('arr',arr); //check the array data
return arr;
})
.catch(err => {
console.log(err);
return [1, 2, 3];
});
}
router.route("/categories").get(async function(req, res, next) {
let arr = await getCategories().catch(err => {
res.status(400).send(err);
});
res.json(arr);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.