在执行另一个函数之前等待一个函数完成

时间:2015-09-29 16:09:47

标签: javascript

我使用此代码基本上切换到我的数据表中的下一行,但是,我已经编程了我的应用程序以检查更改和/或通过提示用户保存它们,然后切换到并处理下一行中的数据表。

然而,我不喜欢这种编码的方法是,在单击OK按钮保存更改之前,另一半代码将被触发。如何进入onclick函数,等待我的RealTimeSave()函数完成将更改写回数据库,然后将视图切换到数据表中的下一行?

var table = document.getElementById("data");
var tbody = table.getElementsByTagName("tbody")[0];

tbody.onclick = function(e) {

    if (document.getElementById('data')) {

        if(!document.getElementById('save').disabled) { 

            if (confirm("IMTS has detected unsaved changes, would you like to save the changes now?") == true) {
                RealTimeSave()
            }
        }

    }

    e = e || window.event;
    var td = e.target || e.srcElement
    var row = (td.tagName == "DIV") ? td.parentNode.parentNode : td.parentNode;

    if (ishigh&&ishigh!=row) {
        ishigh.className = ''
    }
    row.className = row.className==="highlighted" ? "" : "highlighted";
    ishigh=row;

    getdata(row)
}

2 个答案:

答案 0 :(得分:1)

查看promise和deferred对象,因为它们可以解决推迟执行:javascript promises

答案 1 :(得分:0)

您的问题缺乏足够的信息,但根据您对问题的描述判断我假设RealTimeSave()执行了一些异步任务。您可以做的最好的事情是更改负责更新数据库的回调(IndexedDB?),但另一种解决方案是将更新后的逻辑包装在函数表达式中,并将其作为参数传递给setTimeout()另一个参数(延迟)是0。这是一个例子:

// slightly reorganized the code, feel free to stick with your style

var highlighted;
document.querySelector('#data > tbody').addEventListener('click', function (e) {
  if (!document.querySelector('#save').disabled &&
      confirm('IMTS has detected unsaved changes, ' +
              'would you like to save the changes now?')) {
    realTimeSave(); // this triggers an asynchronous task...
  }

  // ...and so does this, but the task is queued
  setTimeout(function () {
    var target = e.target;
    var row = target.parentNode;
    if (target.tagName === 'DIV') {
      row = row.parentNode;
    }
    if (highlighted && highlighted !== row) {
      highlighted.classList.remove('highlighted');
    }
    row.classList.toggle('highlighted');
    highlighted = row;
    getData(row);
  }, 0);
});

由于event loop在JavaScript中的工作原理,作为setTimeout()的第一个参数传递的函数将等到处理之前添加的所有消息(事件和其他消息)。请注意,传递0作为延迟并不能保证函数会立即执行,但您可以确保在所有先前添加的异步任务完成后执行。因此,假设您使用的是IndexedDB,并且您的代码样板文件如下所示:

dbTransaction.oncomplete = function (e) {
  // ...
};
// or
dbRequest.onsuccess = function (e) {
  // ...
};

...使用setTimeout()就足够了。但是,如果您通过AJAX连接到在线数据库界面,那么您唯一的选择(假设承诺 - 在另一个答案中提到 - 不可用)是挂钩AJAX成功回调并相应地更新您的接口逻辑。