链接jquery .when()。then()在一个固定的链调用结束的循环中 [英] chaining jquery .when().then() in a loop with fixed end of chain call

查看:129
本文介绍了链接jquery .when()。then()在一个固定的链调用结束的循环中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能找到的最接近的答案是 https://stackoverflow.com/a/17216555/2834734

The closest answer I could find was this https://stackoverflow.com/a/17216555/2834734


.then最常见的用途是链接ajax请求:

The most common use for .then is chaining ajax requests:

$。ajax({...})。then(function(){
返回$ .ajax({...});})。then(function(){
return $ .ajax({...});})。then(function(){
返回$ .ajax({...});})。then(function(){
return $ .ajax({...});});

这可以很容易地在循环中完成

this can easily be done in a loop

然而,这是我遇到困难的循环程序加上我有一些不寻常的情况。

However it's the looping procedure I'm having difficulty with plus I have some unusual circumstances.

一个简短的解释是,我有一个需要循环的请求数组,有些会调用ajax加载而有些则不会。我需要它们连续运行,但也在最后运行一个特定的函数调用。

A brief explanation is, I have an array of requests that I need to loop through, some will invoke an ajax load and others will not. I need them to run consecutively but also run a specific function call at then end.

这是一个简单的(我希望)我的情况样本:

Here is a simple(I hope) sample of my situation:

      // Here is my flow of logic
       var thingsToDo = new tasks(); // Initiate the constructor, explained below

        // Loop through the requests array and process them consecutively
       for (var i in thingsToDo.requests) {
         $.when(thingsToDo.jqxhr).then(function() {
           thingsToDo.requests[i].fn();
         })
       }
        // Run my final function at the end of the chain.
       $.when(thingsToDo.jqxhr).then(function() {
         runOnceAllComplete();
       });

这是上面的构造函数类。

This is the constructor class the above is based on.

        // Constructor
       function tasks() {
         _tasks_ = this; // automatic global var 
         this.jqxhr = undefined; // Var to monitor ajax calls
         this.requests = [ // list of tasks to run.
           {
             url: 'file1.php',
             fn: function() {
               _tasks_.load(this.url);
               console.log('file1 loaded');
             }
           }, {
             url: 'file2.php',
             fn: function() {
               _tasks_.load(this.url);
               console.log('file2 loaded');
             }
           }, {
             noUrl: true, // Note there is no file to load here
             fn: function() {
               console.log('no file here to load, but process something else');
               $('body').css("background-color", "blue");
             }
           }, {
             url: 'file3.php',
             fn: function() {
               _tasks_.load(this.url);
               console.log('file1 loaded');
             }
           },
         ];
         this.load = function(file) { // This runs the ajax call and resets this.jqxhr             
           this.jqxhr = $.get(file);
         }
       }

       function runOnceAllComplete() {
         alert('hooray!, we finished');
       }

我有一个棘手的部分是请求是动态创建的,所以可以有1个-n许多请求要执行,这就是我选择循环的原因,它们必须按顺序执行。

The tricky part I have is the requests are created dynamically so there can be 1-n many requests to perform, which is why I chose to loop, and they must be performed in that order.

如上所述,一些请求会调用ajax调用,而其他请求可能不会,这似乎不会破坏 $。when()。then( ),但问题是在解析promise之前循环继续,并且我的最终函数在最终请求之前发生。
我还是第一次尝试使用它们来试图理解承诺。

As mentioned some requests will invoke an ajax call and others may not, this doesn't seem to break $.when().then(), but the problem is the loop continues before the promise is resolved and my final function happens before the final request. Still trying to get my head around promises, the first time I've used them.

推荐答案

尝试包括返回语句 fn this.load ;在 fn .promise()链接到 $(body) c $ c>返回一个jQuery promise对象;使用 Function.prototype.apply() $。map() at $。 ()

Try including return statement at fn , this.load ; adding .promise() chained to $("body") at fn to return a jQuery promise object ; using Function.prototype.apply() , $.map() at $.when()

fn: function() {
  // added `return`
  return _tasks_.load(this.url);               
}







this.load = function(file) { 
  this.jqxhr = $.get(file);
  // added `return`
  return this.jqxhr
}



< hr>


fn: function() {
  console.log('no file here to load, but process something else');
  // added `return` , `.promise()`
  return $('body').css("background-color", "blue").promise();
}







$.when.apply($, $.map(thingsToDo.requests, function(task) {
  return task.fn()
})).then(runOnceAllComplete)

另见将一系列Deferreds传递给$ .when() $ .when.apply($,someArray)做什么?


但是我遇到了一个问题,使用.map()在处理下一个请求之前,它不等待每个请求完成
。我需要每个
才能完成,然后再转到下一个。

however I'm encountering a problem, using the .map() it doesn't wait for each request to complete before processing the next one. I need each one to complete before moving to the next.

尝试使用 .queue( ),它将按顺序调用队列中的函数,并且仅在当前函数调用 next

Try using .queue() , which will calls functions in queue sequentially, and only when next is called at current function

$(thingsToDo).queue("tasks", $.map(thingsToDo.requests, function(task) {
  return function(next) {
    // call next function in `"tasks"` queue
    // when current function completes using `.then(next)`
    return task.fn().then(next)
  }
})).dequeue("tasks").promise("tasks").then(runOnceAllComplete)

请参阅 .queue() .promise() ,< a href =https://stackoverflow.com/questions/32028368/execute-function-queue-in-javascript/>在javascript中执行函数队列

这篇关于链接jquery .when()。then()在一个固定的链调用结束的循环中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆