【问题标题】:Javascript method chainingJavascript 方法链
【发布时间】:2011-08-29 04:31:22
【问题描述】:

不知道该怎么说。

假设我有一个进行 AJAX 调用的 JavaScript 方法:

function makeAJAXCalls()
{
    // who knows how long this will take
}

并且我不希望在所有 AJAX 调用完成之前执行下一个函数。我也不想将下一个函数调用放入 AJAX 调用的成功回调中。

有没有办法让我喜欢链接这些,所以在makeAJAXCalls() 完成它需要做的所有事情之前不会调用下一个函数?

【问题讨论】:

  • 为什么不把它投入成功呢?这就是回调的工作原理
  • 同步调用?不过我不建议这样做。
  • 因为我不希望每次调用 AJAX 方法时都调用它,只有在我指定它时才调用它。
  • 那么,只在需要时指定回调。

标签: javascript


【解决方案1】:

你可以使用 jQuery 的 $.when() functionality

$.when(makeAjaxCalls()).done(function () { 
   // Do other things here 
});

如果您希望首先完成所有这些功能,您甚至可以在 when 中添加多个功能。这些都叫Deferred Objects

【讨论】:

  • 这很有趣。它是在我进行绑定后立即调用还是绑定到 AJAX 函数并且仅在调用 AJAX 函数时才被调用?
  • 只有在函数完成后才会触发 done 部分。
  • 这仅在makeAjaxCalls 返回延迟对象时有效。
  • @mike 但是如果 makeAjaxCalls 触发了 ajax 请求,是否会等到所有响应完成后才完成,或者它只是在 makeAjaxCalls 方法退出时触发?这是两个非常不同的东西......
  • @Matt 非常正确...我假设它确实如此:) @hvgotcodes 好问题,我会测试它
【解决方案2】:
var queueCount =0;
function makeAjaxCalls()
{
    queueCount+=7; // or however many calls you need to make.
    // make your ajax calls. onSuccess (or failure), call checkQueue();
}
function checkQueue()
{
    queueCount--;
    if (queueCount <=0)
    {
       doNext();
    }
}

这使得调用异步,这可能是这里的意图。

【讨论】:

  • 谢谢。我们认为这是一种经典的方法。虽然我很喜欢jquery,但有时候通过简单的方式解决问题更容易。
【解决方案3】:

你真的限制了你的选择。 AJAX 本质上是异步的(除非您使用同步的 xhrs,因为它们会冻结浏览器,所以您不想要它)。所以你唯一的选择是在回调中处理它,因为回调是你知道请求已经完成的唯一方式,以及请求完成时数据在哪里被传递。

因为您有多个回调,并且您想等到它们全部完成,您可以在所有回调中放置相同的函数调用,并且该函数可以跟踪哪些响应已经返回,并且只有在所有响应都完成时才继续在那里。

所以你可以做类似的事情

var resultsHolder = [];
var syncer = function(response){
    // add results to resultsHolder on call

    if (resultsHolder.lengh === numberExpected) {
     //proceed
    }
}

然后在你的 makeAllRequests 方法中使用同步器

【讨论】:

    【解决方案4】:

    您可以通过同步调用来实现。

    Example: Synchronous request

    尽管您可能需要注意,这可能会对您的应用程序的其余部分造成不希望的阻塞效应,这可能会质疑使用同步 xhr 的原因。

    【讨论】:

    • @SLaks 我完全同意,但这种可能性仍然存在。
    【解决方案5】:

    如果您使用的是 jQuery 1.5+,则可以进行链式 ajax 调用。这是有效的,因为$.ajax() 返回一个jqXHR,它也是一个Deferred Object

    function makeAjaxCalls()
    {
        return $.ajax(/* snip options */);
    }
    
    function handleSuccess(data)
    {
        // do something with the data
    }
    
    function nextAjax()
    {
        return $.ajax(/* snip other options */);
    }
    
    // then...
    makeAjaxCalls().success(handleSuccess).complete(nextAjax);
    

    【讨论】:

      【解决方案6】:

      您应该将自己的回调作为函数的参数。
      这样,调用者就可以决定下一步该做什么。

      您也可以返回 Deferred 对象。

      【讨论】:

        猜你喜欢
        • 2018-10-12
        • 2019-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-08
        相关资源
        最近更新 更多