如何使用Javascript Promise依次执行AJAX调用

use*_*142 1 javascript ajax jquery asynchronous promise

我正在遍历一个映射,在这里我想用每个映射值作为参数进行一个单独的AJAX调用,以获取一些数据并记录下来。见下文。这是可行的,但我想按地图顺序进行AJAX调用。因为每个调用都是异步的,所以我似乎应该使用promises来顺序执行。但是我对诺言并不陌生,在这里我真的不知道该怎么做。我在这里其他地方看过,但找不到任何东西。请帮忙。

map.forEach(function(url, key) {
   log(url);
});

function log(url) {
    $.ajax({
      url: url, 
      dataType: 'json',
      success: function (result) {
          console.log(result.value);
          console.log(result.name);
          console.log(result.action);
      }
  });
}
Run Code Online (Sandbox Code Playgroud)

Jar*_*a X 5

由于$ .ajax返回一个promise,因此您可以使用promise链接来实现所需的功能

var p = $.when();
map.forEach(function(url, key) {
    p = p.then(function() { 
        return log(url);
    });
});

function log(url) {
    return $.ajax({
        url: url, 
        dataType: 'json',
        success: function (result) {
            console.log(result.value);
            console.log(result.name);
            console.log(result.action);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

注意:上面的代码仅使用jQuery,没有原生的Promise

或使用Array的reduce函数

map.reduce(function(p, url) {
    return p.then(function() { 
        return log(url);
    });
}, $.when());
Run Code Online (Sandbox Code Playgroud)

如果您可以使用ES2015 +,则可以使用本机Promises,

map.reduce((p, url) => p.then(() => log(url)), Promise.resolve());
Run Code Online (Sandbox Code Playgroud)

如果您愿意,也可以这样

function log(url) {
    return $.ajax({
        url: url, 
        dataType: 'json'
    });
}

map.reduce((p, url) => p.then(results => log(url).then(result => results.concat(result))), Promise.resolve([]))
.then(results => {
    results.forEach(result => {
        console.log(result.value);
        console.log(result.name);
        console.log(result.action);
    })
});
Run Code Online (Sandbox Code Playgroud)

区别在于,所有的console.log都将在LAST请求完成后发生(如果失败,则不会发生任何控制台日志)