javascript - 在继续更改 DOM 函数之前如何等待异步数据库调用解析?

标签 javascript node.js mongodb asynchronous synchronous

我正在尝试动态地将元素添加到表中,有点像分类帐。我有一些 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);
    });
}

变更摘要:

  1. fetch(url) 更改为 return fetch(url),从而返回 promise 。
  2. 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/

相关文章:

javascript - 选择框中选定值的开关/大小写用法

javascript - 如何使用管道有条件地显示innerHTML值

javascript - 从node.js中的回调函数获取result.insertId

mongodb - 如何在MongoDB中进行简单的数据挖掘?

mongodb - 存储和查询气象数据大数据集的更好方法是什么

javascript - 如何像浏览器在 html 元素内部那样制作移动响应式 View ?

javascript - float 和偏移 Javascript 值

arrays - 如何在聚合框架中按位置修改数组中的值

javascript - 错误: "EPERM: operation not permitted" while remove directory not emty

node.js - MongoWriteConcernError : No write concern mode named 'majority;' found in replica set configuration at MessageStream. 消息处理程序