Javascript异步AJAX和递归排序

Javascript asynchronous AJAX and recursive sequencing

本文关键字:递归 排序 AJAX 异步 Javascript      更新时间:2023-10-03

我有一种情况,使用同步ajax请求闻起来像蛋糕。

基本上,我需要弄清楚如何对异步请求进行排序,以便下一个请求等待,但我所需要的结构使这变得非常具有挑战性。我会努力解释我拥有什么以及我想完成什么。

  1. 单击按钮
  2. AJAX请求被发送来获得需要做的事情的列表
  3. 列表必须经过for循环,所以步骤一个接一个地进行
  4. 现在是棘手的部分。有些步骤需要额外的ajax请求来获取如何继续的信息,但下一步无法继续,因为上一步没有完成
  5. 一个更棘手的部分是,一个步骤可能有另一个完整的序列。此外,一些步骤会向用户提供提示,并且必须等待答案才能继续

我现在将尝试解释我目前的结构。

  1. initSequence(sequenceName,params);此函数获取序列的名称,从服务器请求列表并将其传递给下一个函数:
  2. runSequence(序列,params);此函数是执行for循环的函数。对于序列中的每个操作,它都会进行最少的检查,并使用下一个函数运行该操作:
  3. executeAction(actionName,actionArgument,params);这个函数基本上是一个代码的母负载,它知道什么时候该根据传递的参数来做什么。此函数还可以启动另一个initSequence();这在理论上将使其成为递归行为

对这些请求进行排队的理想方式是什么?我看到了一些关于使用承诺的东西。但没有弄清楚如何在不同的函数调用之间链接它们,或者它如何与递归一起工作?

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

编辑:可能完全工作代码:

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链接

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

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