Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在继续使用函数更改DOM之前,如何等待异步数据库调用的解析?_Javascript_Node.js_Mongodb_Asynchronous_Synchronous - Fatal编程技术网

Javascript 在继续使用函数更改DOM之前,如何等待异步数据库调用的解析?

Javascript 在继续使用函数更改DOM之前,如何等待异步数据库调用的解析?,javascript,node.js,mongodb,asynchronous,synchronous,Javascript,Node.js,Mongodb,Asynchronous,Synchronous,我试图动态地向表中添加元素,有点像分类账。我有几个HTML按钮。按钮从MongoDB集合动态加载到DOM。我使用NodeJS,使用PUG/Jade作为视图引擎,并将DB中的_id值作为每个按钮的id值。通过这种方式,我可以使用onclick函数查询数据库中的其他属性 每次单击按钮时,我都会对后端运行一个获取调用,以获取存储在MongoDB中的price属性: function getPriceFromDatabase() { var target = event.target; var id =

我试图动态地向表中添加元素,有点像分类账。我有几个HTML按钮。按钮从MongoDB集合动态加载到DOM。我使用NodeJS,使用PUG/Jade作为视图引擎,并将DB中的_id值作为每个按钮的id值。通过这种方式,我可以使用onclick函数查询数据库中的其他属性

每次单击按钮时,我都会对后端运行一个获取调用,以获取存储在MongoDB中的price属性:

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()的结果

这意味着我得到了一个表,其中第一列正确地说明了单击的按钮的名称,但价格列未定义。查询数据库并返回一个值只需要一段时间,到它发生时,调用查询的函数已经完成

我有什么选择?我还是使用承诺和异步函数的新手。我知道fetch返回一个承诺作为响应对象,这就是为什么我可以使用

我已尝试将DOM表函数更改为:

getPriceFromDatabase().then( [construct the rest of the table elements] ) 
这是无效的,因为.then()不是该函数的属性,因为它不返回承诺。我能做什么

我已经试过了

异步getPriceFromDatabase(){},但它仍然给我一个无法使用的错误

我怎样才能解决这个问题?我必须使用新的Promise()吗?如果有人能给我指出正确的方向,我将不胜感激

getPriceFromDatabase()
是一个异步函数。您需要从中返回承诺,并对返回的承诺使用
。然后()

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)
    ,从而返回承诺
  • var priceOfItem=getPriceFromDatabase()
    更改为
    getPriceFromDatabase。然后(…)
  • 此外,您确实应该将
    事件
    传递到这两个函数中,而不是依赖全局函数


    我尝试将DOM表函数更改为:
    getPriceFromDatabase()。然后([构造其余的表元素])

    这对您不起作用,因为您没有从
    getPriceFromDatabase()
    返回承诺,因此返回值上没有
    .then()
    处理程序

    我尝试了
    异步getPriceFromDatabase(){}
    ,但它仍然给了我一个无法使用的错误


    同样的问题。你仍然必须兑现承诺。

    回答得非常有帮助。你能详细解释一下你对globals的意思吗?我认为这些变量是局部变量,在onClick函数运行后会消失。您的意思是我应该简单地使用“return fetch(event.target.id)”,而不是在fetch调用之前声明它们吗?还是我错过了你想告诉我的?而且,我也不知道我会那样回来。那么,fetch本身就是一个承诺,并且包含一个承诺,其中包含一个响应对象?或者return fetch(…)是返回响应对象本身的一种方法吗?@Mikhail-
    fetch()
    返回一个承诺。因此,当您执行
    return fetch()
    时,您将从主机函数返回一个承诺。关于
    事件
    我的意思是,您没有将其传递到任何函数中,因此您显然在使用全局
    事件
    对象。在异步函数中,这不是一件好事,因为全局
    事件在使用它之前可能会发生更改。您应该将事件传递到
    createTableElement(event)
    中,然后再次将其传递到
    getPriceFromDatabase(event)
    。实际上,
    getPriceFromDatabase()
    如果您传入
    id
    则通常更有用。我没有考虑到事件的变化,因为此时我的大多数呼叫都相对较快。我遵照您的建议,将onClick函数更改为
    createTableElement(this.id)
    。通过函数链传递它基本上消除了使用事件对象的需要。再次感谢你的提示。