1

我正试图集中精力协调异步操作。我需要一点帮助理解:

  1. 为什么使用 while 循环等待操作完成是一个坏主意并且不起作用,并且
  2. 如果有在 jQuery 函数上使用回调的可行替代方案

大多数情况下,将回调添加到像 $.get() 这样的异步函数效果很好。然而,在某种程度上,这确实决定了我不喜欢的代码的编写方式和位置。

$(function() {

    var r = AjaxResults( page );

    // loop prevents further processing until GetResults() is done
    while( isComplete == false )
    isComplete = $('body').data('isComplete');

    // reset isComplete boolean
    $('body').data('isComplete', false);

    // this will only continue after GetResults() has exited
    paintTheTownRed();
    var whateverElse = true;
});

function AjaxResults( page ) {

   // do something before async operation
   switch( page ){
       case '1': {...} break;
       ...
       default: break;
   } 

   $.getJSON("/controller/page", null, function(data) {

       // do something after async operation
       {...}

       $('body').data('isComplete', true);
       return data;
   });
}
4

5 回答 5

8

因为它会刺激我的 CPU 并极大地刺激我。

编写代码的位置几乎从不由异步/同步决定;函数是函数,无论它们是匿名的并内联编写的,还是命名并作为引用传递的。

此外,promise 和延迟对象有助于决定在哪里/如何实现功能。

有关其他详细信息和想法,请参阅.when(文档)之类的内容,但还有其他使用它们的方法。

于 2012-07-13T17:06:02.043 回答
2

简而言之,您不应该这样做,因为这将是非常糟糕的用户体验,并且会严重激怒大多数/所有观众。充其量它会刺激 CPU 并不必要地耗尽观众的电池。在最坏的情况下,观众会认为他们的浏览器冻结/挂起。

因为 javascript 是单线程的,并且单线程与浏览器中的用户事件处理相关联,所以如果您使用 while 循环循环等待异步事件完成,您将在 while 循环期间锁定浏览器。您可能还会发现某些浏览器会给用户一个警告,提示您运行的 javascript 过长。

目前没有替代某种类型的回调用于 javascript 中的异步编程。如果您想使用异步操作,那么您必须使您的编程风格适应它们的工作方式,以保持良好的用户体验。是的,这意味着调整你的编程风格,但这是为了保持良好的用户体验而付出的代价。 如果您想对此进行调查,延迟对象可以为您提供一种更令人愉悦的代码编写方式(它仍然是回调,但似乎少了一点)。

做你提议的事情是将你的编程便利性放在用户体验之前,这只是一个糟糕/懒惰的程序员的标志,他们的目标/优先级似乎倒退了。

仅供参考,即使在允许并且可以工作的环境中(如本机 Windows 开发),这也是一种糟糕的编程实践。

于 2012-07-13T17:08:33.157 回答
1

大多数情况下,向异步函数添加回调$.get()效果很好。然而,在某种程度上,这确实决定了我不喜欢的代码的编写方式和位置。

不再需要直接向 AJAX 函数添加回调。

使用 jQuery deferred objects让您在不需要过多嵌套的情况下编写代码:

function AjaxResults( page ) {
    ...  // prep
    return $.getJSON("/controller/page", null)
        .done(function(data) {
            // always do this
        });
}

AjaxResults(page).done(paintTheTownRed);

无论如何,请按照此处所示放置您自己的complete处理程序,但是通过返回对象,您有机会做额外的事情,而无需传递大量回调或嵌套您的代码。$.getJSONjqXHR

于 2012-07-13T17:11:36.993 回答
0

如果您的问题是您不喜欢定义在 $.get() 中调用的函数,那么请务必将其写为单独的函数:

$(function() {

    AjaxResults( page );

});

function AjaxResults( page ) {

   // do something before async operation
   switch( page ){
       case '1': {...} break;
       ...
       default: break;
   } 

   $.getJSON("/controller/page", null, doWhatever);
}

function doWhatever(data) {
    paintTheTownRed();
    var whateverElse = true;
}
于 2012-07-13T17:12:42.913 回答
0

嗯,这是一个坏主意,因为它不起作用。永远不会调用回调函数,因为您处于 while 循环中,因此布尔值不会更改为true,因此它是一个无限循环

现在,为什么实际的同步请求是一个坏主意,因为它们冻结了 UI 并使我认为选项卡崩溃了。但是,是的,同步请求是回调的替代方案。

于 2012-07-13T17:13:00.627 回答