Javascript异步AJAX和递归排序

时间:2016-03-31 11:06:21

标签: javascript jquery ajax asynchronous recursion

我遇到使用同步ajax请求闻起来像蛋糕的情况。

基本上我需要弄清楚如何对异步请求进行排序,以便下一个请求等待,但是我需要它的结构使得这非常具有挑战性。我会试着解释一下我的想法和想要完成的事情。

  1. 点击一个按钮
  2. 发送AJAX请求以获取需要完成的事项列表。
  3. 列表必须经过for循环,所以步骤一个接一个。
  4. 现在是棘手的部分。某些步骤需要额外的ajax请求来获取有关如何继续的信息,但是在前一个步骤未完成的情况下,后续步骤无法继续。
  5. 更棘手的部分是,一步可能有另一个序列。此外,一些步骤会向用户发出提示,必须等待答案才能继续。
  6. 我现在将尝试解释我目前的结构。

    1. initSequence(sequenceName,params);此函数采用序列的名称,从服务器请求列表并将其传递给下一个函数:
    2. runSequence(sequence,params);该函数是执行for循环的函数。对于序列中的每个操作,它执行最少的检查并使用下一个函数运行操作:
    3. executeAction(actionName,actionArgument,params);这个函数基本上是一堆代码,它知道什么时候根据传递的参数做什么。这个函数也可以启动另一个initSequence();这在理论上会使这成为一种递归行为。
    4. 将这些请求排队的理想方法是什么?我见过有关使用承诺的事情。但是没有设法弄清楚如何在不同的函数调用之间链接它们或者它如何与递归一起工作?

      任何想法和帮助将不胜感激。

      编辑:可能完全正常工作的代码:

      var listf = ['print', 'ask', 'send', 'list', 'done'];
      var lists = ['print2', 'ask2', 'done2'];
      
      var promiseFor = (function(condition, action, value) {
        var promise = new Promise(function(resolve, reject) {
          if(!condition(value)) return;
          return action(value).then(promiseFor.bind(null, condition, action));
        });
        return promise;
      });
      
      var initSequence = (function(n) {
        var promise = new Promise(function(resolve, reject) {
          if(n == 1) {
            return runSequence(listf);
          }
          return runSequence(lists);
        });
        return promise;
      });
      
      var runSequence = (function(list) {
        var promise = new Promise(function(resolve, reject) {
          var count = 0;
          promiseFor(function(count) {
            return count < list.length;
          }, function(count) {
            return executeAction(list[count]).then(function(result) {
              return ++count;
            });
          }, 0).then(console.log.bind(console, 'for done'));
        });
      });
      
      var executeAction = (function(action) {
        var promise = new Promise(function(resolve, reject) {
          if(action == 'print') document.getElementById('output').innerHTML += 'Some text<br>';
          if(action == 'print2') document.getElementById('output').innerHTML += 'Some text 2<br>';
          if(action == 'ask') {
            document.getElementById('output').innerHTML += 'Alert 1 for pause<br>';
            alert('pausing');
          }
          if(action == 'ask2') {
            document.getElementById('output').innerHTML += 'Alert 2 for pause<br>';
            alert('pausing again');
          }
          if(action == 'send') {
            setTimeout(function() {
              document.getElementById('output').innerHTML += 'Text after delay<br>';
              resolve(true);
            }, 2000);
            return;
      
          }
          if(action == 'list') {
            document.getElementById('output').innerHTML += 'Starting subsequence<br>';
            initSequence(2);
          }
          if(action == 'done') document.getElementById('output').innerHTML += 'Sequence done<br>';
          if(action == 'done2') document.getElementById('output').innerHTML += 'Sequence 2 done<br>';
          resolve(true);
        });
        return promise;
      });
      
      initSequence(1);
      

      Codepen link for the code

1 个答案:

答案 0 :(得分:0)

您应该使用promises将请求和执行链接在一起。

var firstMethod = function() {
   var promise = new Promise(function(resolve, reject){
      setTimeout(function() {
         console.log('first method completed');
         resolve({data: '123'});
      }, 2000);
   });
   return promise;
};


var secondMethod = function(someStuff) {
   var promise = new Promise(function(resolve, reject){
      setTimeout(function() {
         console.log('second method completed');
         resolve({newData: someStuff.data + ' some more data'});
      }, 2000);
   });
   return promise;
};

var thirdMethod = function(someStuff) {
   var promise = new Promise(function(resolve, reject){
      setTimeout(function() {
         console.log('third method completed');
         resolve({result: someStuff.newData});
      }, 3000);
   });
   return promise;
};

firstMethod()
   .then(secondMethod)
   .then(thirdMethod)

//... etc.

以下是一些可能有用的资源链接

https://html5hive.org/how-to-chain-javascript-promises/ http://www.html5rocks.com/en/tutorials/es6/promises/

https://github.com/kriskowal/q