jquery post call函数n次,但在调用下一个之前等待每个函数完成

时间:2017-08-08 16:57:03

标签: javascript jquery

我有一个列表,我通过$.post一次向PHP发送一个。我想在打电话给下一个之前等待每一个完成。我想用JS做这个,不要用PHP循环,因为我希望每个都显示返回值。

var list = ["a", "b", "c"];
for (i = 0; i < list.length; i++) {
  $.post(con, {
    callScript: list[i],
  }, function(data, status) {
    //Do stuff here with the data on success

  });
}

我查看了$.when,但却无法理清如何使用它。以下示例假定存在一定数量的函数而不是相同的函数n次。我也知道不允许异步错误。

有没有办法让它运行?

3 个答案:

答案 0 :(得分:3)

递归是你在这里的好朋友。您可以创建一个为每个项调用自身的函数,在完成当前项的异步操作后调用下一个函数。当我们用完项目时,递归就会停止。

function postInOrder(list, index = 0) {
  if (index < list.length) {
    $.post(con, {
      callScript: list[index],
    }, function success(data, status) {
      // do stuff here with the data on success
      // ...
      postInOrder(list, index + 1); // <-- run next script on completion
    });
  }
}

postInOrder(["a", "b", "c"])

以下是使用假post方法的示例:

&#13;
&#13;
function postInOrder(list, index = 0) {
  if (index < list.length) {
    console.log(`Start: ${list[index]}`)
    post(function success() {
      console.log(`Finish: ${list[index]}`)
      postInOrder(list, index + 1); // <-- run next script on completion
    });
  }
}

postInOrder(["a", "b", "c"])

function post(cb) { setTimeout(cb, 1000); }
&#13;
&#13;
&#13;

答案 1 :(得分:3)

您也可以将其减少到承诺队列:

list.reduce(function(prom,listEl){
  return prom.then(function(){
   return new Promise(function(next){
    $.post(con, {
      callScript: listEl,
    }, function(data, status) {
      //Do stuff here with the data on success
      next();
    });
  });
 });
},Promise.resolve());

(我认为包装成一个承诺不是必要的,可能有人对jquerys语法保持谨慎,可以自由编辑;)

答案 2 :(得分:0)

有一个非常广泛使用的库叫做#34; async&#34;这使得这种事情变得非常容易。以下是async series的文档,这可能是您想要在此处执行的操作。

以下是文档中的示例:

async.series([
    function(callback) {
        // do some stuff ...
        callback(null, 'one');
    },
    function(callback) {
        // do some more stuff ...
        callback(null, 'two');
    }
],
// optional callback
function(err, results) {
    // results is now equal to ['one', 'two']
});

如果出现错误,回调的模式将传递错误作为第一个参数,否则传递null作为第一个参数,然后传递实际返回值作为第二个参数。该模式在服务器和浏览器中的所有异步JavaScript中使用。

最后一个函数是系列完成后执行的函数。

你知道变量可以是JavaScript中的函数并构建你的队列,你也会变得棘手:

var processMe = [];

processMe.push(callScript('two'));
processMe.push(callScript('four'));
processMe.push(callScript('six'));

async.series([ processMe ],
function(err, results) {
    // results is now equal to ['two', 'four', 'six']
});

function callScript(value, callback) {
  // do something here
  callback(null, value);
}

如果您需要将结果从一个步骤传递到另一个步骤,也可以使用waterfall

如果它真的是多次相同的代码,请使用times运算符简单地迭代相同的函数N次:

// Pretend this is some complicated async factory
var createUser = function(id, callback) {
    callback(null, {
        id: 'user' + id
    });
};

// generate 5 users
async.times(5, function(n, next) {
    createUser(n, function(err, user) {
        next(err, user);
    });
}, function(err, users) {
    // we should now have 5 users
});