如何在jQuery命令链的末尾调用函数作为参数?

时间:2011-10-06 15:53:19

标签: jquery

...如果最后一个命令没有回调函数?例如

$(something).remove(other_thing).append(new_thing)

追加没有回调函数,所以我的问题是,是否有一个jQuery方法(或其他方式)在一串命令之后调用传递的函数?该功能不必影响当前选择。

编辑:我知道这个例子中的方法不需要很长时间,因此不需要回调,但这只是我能想到的第一个例子。所以请把它想象成不是这样的

2 个答案:

答案 0 :(得分:4)

鉴于append很快完成,没有必要进行回调。如果你想调用另一个函数,只需在下一行执行。

$(something).remove(other_thing).append(new_thing);
yourFunction();

<强>更新

有些函数是同步的,有些是异步的。当执行异步函数(如$ .ajax)时,无论异步函数是否已完成,javascript都会立即执行下一行代码。另一方面,同步函数阻止javascript执行任何其他代码,直到它完成。异步函数接受回调的原因是执行必须等待异步函数在运行之前完成的代码。不接受回调的函数是同步的,并且是故意阻塞或者不期望长时间运行。

Synchronous versus asynchronous calls

答案 1 :(得分:3)

要扩展Craig的答案,您只需在下一个语句中正常调用您的函数。

回调函数的目的是让你可以在其他东西之后做一些事情 - 这将花费不确定的时间,比如网络(AJAX)调用完成。关键是其他操作不会阻止。换句话说,它发生 - 或者,从你的脚本的角度来看,似乎发生在另一个线程上。

考虑一下AJAX调用的工作原理。

var d;
$.get('/something', function(r) {
    // this is a callback function
    d = r;
    alert(d);
});
// this is the next statement
console.log(d);

$.get的调用首先在此程序中执行。第一个参数是您要获取的URL;第二个是匿名回调。它将在浏览器连接到服务器,请求/something并最终收到响应后执行。当脚本继续执行时,这些事情会在后台发生。

console.log的调用在调用$.get后执行。由于$.get立即返回 ,因此日志调用在浏览器甚至有机会连接到服务器之前发生。这意味着d未定义,而您对console.log的调用只会显示“未定义”。

这是回调的有用性发挥作用的地方。当后台请求完成时,浏览器会在jQuery用于发出请求的XHR对象上触发一个事件。然后jQuery使用请求的结果调用您的回调函数。在此功能中,我们现在拥有数据,可以设置d,并且对alert的调用包含您的数据。魔术!

现在考虑jQuery的DOM操作函数(如append)如何工作。 它们是同步的。这意味着您对append 阻止的调用 - 以及您的脚本无法执行任何操作 - 直到该功能完成所有工作。< / p>

这是浏览器的本机DOM操作功能如何工作的结果。在完成对DOM的更改之前,它们不会返回。

因此,jQuery在DOM操作方法(或任何其他同步方法)上提供回调函数是没有用的。

以下是append从极其简化的角度看起来的样子:

$.fn.append = function(elem) {
    // do stuff, specifically
    this.appendChild(elem);
};

如果我们添加了一个回调选项,它会是什么样子:

$.fn.append = function(elem, callback) {
    // do stuff, specifically
    this.appendChild(elem);
    if (callback) callback();
};

现在,你将分别从代码中做些什么:

$('#something').append('<b>Foo</b>');
addBar();
console.log('Done');

$('#something').append('<b>Foo</b>', function() {
    addBar();
});
console.log('Done');

这两个片段每次都保证执行完全相同。

  1. 您致电.append。如果jQuery有魔力,jQuery会运行一些,最终会调用appendChild上的原生#something
  2. appendChild将新节点附加到#something。修改DOM,并更新内部数据结构以反映更改。如果要附加许多节点,则可能需要一段时间。
  3. 控件从appendChild返回。
  4. 接下来会发生什么取决于我们谈论的'版本'。
    • 在正常版本中:
      1. 控件从.append()返回。
      2. 执行脚本的下一个语句。在这种情况下,我们会调用addBar()
      3. 完成addBar后,将调用下一个语句console.log('Done')
    • 在回调版本中:
      1. .append()会检查您是否提供了回叫,而且还有,所以...
      2. .append()调用回调函数。
      3. 在回调中,我们致电addBar().
      4. addBar完成时,控制权返回回调函数,由于函数中没有其他内容,它也会返回。
      5. 控件现已返回.append(),并且该功能无需执行任何操作,因此控件将从.append()返回。
      6. 执行脚本的下一个语句。 console.log('Done')被称为。{/ li>
  5. 如您所见,无论我们采用哪种方式,

    1. 该元素将附加到DOM。
    2. addBar()被召唤。
    3. console.log()被召唤。
    4. 作为一项规则:如果jQuery函数没有提供传递回调的选项,则该函数是同步的,因此您可以在下一行继续执行下一步。


      编辑:如果你想在一个链中间调用一个函数,jQuery不提供内置的任何东西,但我们可以编写our own plugin

      jQuery.fn.invoke = function() {
          var args = Array.prototype.slice.call(arguments), fn = args.shift();
          fn.apply(this, args);
          return this;
      };
      

      这将您想要调用的函数作为第一个参数,然后将其余参数传递给该函数。在函数中,this引用链中的jQuery对象。函数的返回值被忽略。 Demo.