我正在尝试动态地将元素添加到表中,有点像分类帐。我有一些 HTML 按钮。这些按钮会从 MongoDB 集合动态加载到 DOM。我使用 NodeJS,使用 PUG/Jade 作为 View 引擎,并将数据库中的 _id 值作为每个按钮的 id 值。这样我就可以使用 onclick 函数在数据库中查询其他属性。
每次单击按钮时,我都会对后端运行 fetch 调用,获取存储在 MongoDB 中的价格属性:
function getPriceFromDatabase() {
var target = event.target;
var id = target.id;
var url = '/menus/' + id;
fetch(url, {
method: 'GET'
}).then(function(res){
if(!res.ok) console.log("Error");
else return res.json().then(function(result){
var returnedItem = JSON.parse(result)
console.log("Item Price: " + returnedItem[0].itemPrice);
return returnedItem[0].itemPrice;
}).catch(function(err){
console.log(err);
});
});
}
这很好用。
我的问题是当我尝试调用此函数向表中添加新行时。
function createTableElement () {
var newTableRow = document.createElement("tr");
var target = event.target;
var nameCell = document.createElement("td");
var nameText = document.createTextNode(target.textContent);
nameCell.appendChild(nameText);
newTableRow.appendChild(nameCell);
var priceOfItem = getPriceFromDatabase()
var priceCell = document.createElement("td");
var priceText = document.createTextNode(priceOfItem);
priceCell.appendChild(priceText);
newTableRow.appendChild(priceCell);
ledgerTable.appendChild(newTableRow);
}
该函数无需等待 getPriceFromDatabase() 结果即可运行
这意味着我得到一个表,其中第一列正确地说明了所单击的按钮的名称,但价格列未定义。查询数据库并返回一个值只是需要一些时间,而此时调用查询的函数已经完成。
我有什么选择?我对于使用 Promise 和异步函数还是个新手。我知道 fetch 返回一个 promise 作为响应对象,这就是为什么我可以使用 .then()
我尝试将 DOM 表函数更改为:
getPriceFromDatabase().then( [construct the rest of the table elements] )
这是无效的,因为 .then() 不是该函数的属性,因为它不返回 promise 。我能做什么?
我尝试过这样做
async getPriceFromDatabase() {},但它仍然给我一个错误,我无法使用 .then()
我该如何解决这个问题?一定要用new Promise()吗?如果有人能指出我正确的方向,我将不胜感激。
最佳答案
getPriceFromDatabase()
是一个异步函数。您需要从中返回 promise ,并对返回的 promise 使用 .then()
:
function getPriceFromDatabase() {
var target = event.target;
var id = target.id;
var url = '/menus/' + id;
return fetch(url, {
method: 'GET'
}).then(function(res){
if(!res.ok) console.log("Error");
else return res.json().then(function(result){
var returnedItem = JSON.parse(result)
console.log("Item Price: " + returnedItem[0].itemPrice);
return returnedItem[0].itemPrice;
}).catch(function(err){
console.log(err);
throw err;
});
});
}
function createTableElement () {
var newTableRow = document.createElement("tr");
var target = event.target;
var nameCell = document.createElement("td");
var nameText = document.createTextNode(target.textContent);
nameCell.appendChild(nameText);
newTableRow.appendChild(nameCell);
getPriceFromDatabase().then(function(priceOfItem) {
var priceCell = document.createElement("td");
var priceText = document.createTextNode(priceOfItem);
priceCell.appendChild(priceText);
newTableRow.appendChild(priceCell);
ledgerTable.appendChild(newTableRow);
});
}
变更摘要:
fetch(url)
更改为return fetch(url)
,从而返回 promise 。var PriceOfItem = getPriceFromDatabase()
更改为getPriceFromDatabase.then(...)
。
此外,您确实应该将事件
传递到两个函数中,而不是依赖于全局函数。
I have tried changing my DOM-table function to something like:
getPriceFromDatabase().then( [construct the rest of the table elements] )
.
这对您不起作用,因为您没有从 getPriceFromDatabase()
返回 promise ,因此返回值上没有 .then()
处理程序。
I tried
async getPriceFromDatabase() {}
, but it still gives me an error that I can't use.then()
同样的问题。你还是要返回 promise 的。
关于javascript - 在继续更改 DOM 函数之前如何等待异步数据库调用解析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47233387/