如何正确链接 ajax 调用?

How do I chain ajax calls properly?

使用 jQuery 3.2.1 我正在像这样链接对 $.ajax 的调用:

function get(i) {
    return $.ajax(...)
      .done(function() { console.log('get done: ' + i) })
      .fail(function() { console.log('get failed: ' + i) })
}

var p = Promise.resolve();
for (var i = 0; i < len; i++) {
    p = p.then(get(i));
}

p.done(function() { console.log('Finished') });

并且我希望在对 i=0 的调用解决之前,对 i=1 的 ajax 调用不会执行。同样,最后的 done() 应该等待所有调用按顺序执行

实际上我先看到了 'Finished',然后才看到其他任何东西,并且 'get done' 以随机顺序返回(我猜是第一个完成的第一个返回)。

我习惯了 Bluebird 的工作方式。我做错了什么?

* 附录一 *

补充一下,我正在加载 javascript 个具有依赖关系的文件,因此需要按顺序加载。因此,第一个 必须 在第二个提取开始之前完成,否则依赖关系将失败

有两个问题:

  • get 函数立即执行,而 then 方法应该获取对该函数的引用,以便稍后由 Promise 实现执行。所以替换:

    p = p.then(get(i));
    

    与:

    p = p.then(get.bind(null,i));
    
  • JavaScript的原生promise没有暴露done方法,所以替换:

    p.done(function() { console.log('Finished') });
    

    与:

    p.then(function() { console.log('Finished') });
    

您可能还应该添加一个 catch 对最终承诺的调用。

更正版本:

function get(i) {
    return $.ajax('https://jsonplaceholder.typicode.com/posts/'+(i+1))
      .done(function() { console.log('get done: ' + i) })
      .fail(function(err) { console.log('get failed: ' + i) })
}

var len = 4;
var p = Promise.resolve();
for (var i = 0; i < len; i++) {
    p = p.then(get.bind(null,i));
}

p.then(function() { console.log('Finished') })
 .catch(function () { console.log('Error occurred') });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>