【问题标题】:JQuery/JavaScript - Timing problemsJQuery/JavaScript - 时间问题
【发布时间】:2018-11-14 17:43:22
【问题描述】:

我创建了一个我试图实例化的类,以查看它是否以我想要的方式处理,并且它工作正常。

实际上,没有我想的那么好,check[i].id() 只会在我在each 循环处暂停控制台时出现在控制台中。

否则,什么都不会炫耀,check 将是undefined。我真的不明白问题出在哪里,这是我第一次遇到这个时间问题。我想知道问题是否来自我的 AJAX 请求太慢,但它不应该在填充 check var 之前等待计算吗?

这是代码,为了清楚起见,我稍微修改了一下:

var Form = function(formSelector, buttonsSelector) {
  var id;

  return {
    // Index of specific form
    setId: function(val) {
      (!isNaN(val)) ? id = val: console.log('Id must be integer')
    },
    id: function() {
      return id
    },

    // Get selectors
    formSelector: function() {
      return formSelector
    },
    buttonsSelector: function() {
      return buttonsSelector
    },

    // Get all DOM elements
    getAll: function() {
      return $(formSelector)
    },

    // Get id related elements
    get: function() {
      return $(this.getAll()).get(id)
    },
    buttons: function() {
      var buttons = $(this.get()).find(buttonsSelector);
      var elements = [];

      var proceed = $.ajax({
        url: 'myURL.php',
        dataType: 'json'
      }).done(function(data) {
        $(buttons).each(function(i) {
          if ((data.id()).includes($(buttons[i]).attr('id'))) {
            var element = new Buttons($(buttons[i]), data[i].id);

            elements.push(element);
          }
        });

        return true;
      });

      if (proceed) return elements;
    }
  }
}

$(function() {
  var test = new Form('.whatever', '.whatever2');
  var check = test.buttons();

  $(check).each(function(i) {
    console.log(check[i].id());
  });
});

谢谢!

【问题讨论】:

  • 在代码修改后编辑了一些错误
  • 在 ajax 完成之前返回元素。尝试接受回调并在 ajax 完成时使用元素调用它(即在 done 内)
  • 甚至返回一个承诺(来自buttons 方法)并使用async/await 以便之后处理它们
  • @NikosM。谢谢您的回答。不过,我怎么知道 done 内的 ajax 何时完成?我尝试将 complete: function () { return elements } 添加到我的 AJAX 请求中,但它仍然无法正常工作
  • 您需要在buttons 方法中接受一个回调函数,然后在donecomplete 上调用此回调并将元素也传递给它。不只是返回不起作用的元素,没有人可以接受它们

标签: javascript jquery timing


【解决方案1】:

例如,在您的 buttons 方法中接受回调,如下所示

//.. rest class as is, only buttons method cahnges
buttons: function(callback) {
  var buttons = $(this.get()).find(buttonsSelector);
  var elements = [];

  var proceed = $.ajax({
    url: 'myURL.php',
    dataType: 'json'
  }).done(function(data) {
    $(buttons).each(function(i) {
      if ((data.id()).includes($(buttons[i]).attr('id'))) {
        var element = new Buttons($(buttons[i]), data[i].id);

        elements.push(element);
      }
    });

    if (callback) callback(elements);
    return true;
  });
}

那么你可以这样做:

$(function() {
  var test = new Form('.whatever', '.whatever2');
  test.buttons(function(elements){
     $(elements).each(function(i) {
       console.log(elements[i].id());
     });
});

});

ajax 调用(以及 javascript 中的许多其他进程)是异步的,这意味着它在某个时间开始并在另一个时间结束,而执行不会暂停等待它完成,然后再执行程序流中的下一条语句。

发生这种情况的原因有很多,例如进程需要查询一些不能立即使用的资源等等。因此,在启动过程和返回结果方面存在一些延迟。

为了在等待时NOT BLOCK当前执行线程,进程变为异步并继续执行(这就是return不等待加载的原因结果但返回空数组)。

因此需要一种方法来回调调用者准备就绪时的结果。出于这个原因,callbacks and/or promises 用于处理这种类型的异步编程。回调不会像您想象的那样暂停执行,而是在结果准备好时调用它,因此通过回调函数调用原始调用者,并将结果作为参数传递。学习异步 javascript、回调和承诺,了解它的含义以及如何使用它们(参见上面的链接)。

【讨论】:

  • 好的,我现在明白我做错了什么,谢谢您的时间,好先生
  • @Snite,如果这解决了您的问题,请接受答案。在 stackoverflow 上,有人试图提供帮助,但至少应该得到认可
  • 完成。它运作良好。虽然我想知道为什么像这样的回调函数会等待前面的代码执行而不是 done() 函数中的“返回元素”。为什么它在返回任何东西之前不等待循环首先运行?为什么函数会等待它运行?
  • @Snite,ajax 调用是异步的,这意味着它现在执行并且结果在一段时间后准备好(但执行不会暂停等待完成),而返回立即发生。因此,需要一种方法在调用完成时用结果回调调用者。这就是异步编程使用回调和/或承诺的原因,因为执行不会暂停,并且需要一种方法在完成时将结果传回
  • @Snite,用异步编程的一些解释和进一步研究的链接更新了我的答案
猜你喜欢
  • 1970-01-01
  • 2011-02-18
  • 2011-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-04
  • 1970-01-01
相关资源
最近更新 更多