如何使用Ajax调用链接两个promise并合并结果?

时间:2018-03-27 10:33:33

标签: javascript promise

我有这段代码:

loadData: function() {
    return new Promise(function(resolve, reject) {
        $.ajax({ dataType: 'json', url: url1}).done(function(r) { resolve(r); });               
    });
},

drawGraph: function(stats) {
    // do stuff with the stats
},

// lower down...
this.loadData().then(this.drawGraph);

工作正常。但是现在我想在调用drawGraph之前进行另一个Ajax调用并将数据组合成两个结果。

这是我尝试过的:

loadSiteTraffic: function() {
    return new Promise(function(resolve, reject) {
        return $.ajax({ dataType: 'json', url: url1}).done(function(r) { resolve(r); });                
    }).then(function(results1) {
        return $.ajax({ dataType: 'json', url: url2}).done(function(r) { resolve(r); });
    }).then(function(results1, results2) {
        return results1 + results2;
    });
}

但是现在我Uncaught ReferenceError: resolve is not defined第二次出现resolve

我想这就是我如何将resolve传递给第二个电话。 但我想继续第一次通话的结果。我应该做什么呢?

也许我需要制作两个单独的loadData函数,从另一个调用一个函数,并以某种方式将结果合并到第三个函数中??

4 个答案:

答案 0 :(得分:1)

你目前正在做的事情是矫枉过正。你不需要$.ajax调用Promise构造函数包装器(除非你在下面做了一些复杂的异步操作),因为$.ajax已经暴露出类似承诺的then处理程序。

此外,您的两个电话都不相互依赖。因此,您可以同时拨打两个电话,并使用$.when

合并结果
loadSiteTraffic: function() {
    return $.when({
      result1: $.ajax({ dataType: 'json', url: url1}),
      result2: $.ajax({ dataType: 'json', url: url2})
    })
    .then(function(resp) {
      return resp.result1 + resp.result2;
    });
}

在您的代码中,您遇到未定义的resolve,因为它不适用于then回调。

答案 1 :(得分:0)

我通常会像这样做我的ajax调用:

$.ajax({ 
    dataType: 'json', 
    url: url1,
    success: function (res1) {
       // Do stuff with res1
       $.ajax({ 
          dataType: 'json', 
          url: url2,
          success: function (res2) {
             // Do stuff with res2
             return res1 + res2;
          ),
       });
    ),
});

这样一来,电话就会“等待”彼此完成。

答案 2 :(得分:0)

您可以创建一个包装ajax调用并返回promise的泛型方法:

load: function(param) {
  return new Promise(function(resolve, reject) {
    $.ajax(param).done(function(r) { resolve(r); });          
  });
},

loadData: function() {
    return Promise.all([
        this.load({ dataType: 'json', url: url1}),
        this.load({ dataType: 'json', url: url2}),
    ]).then(function([results1, results2]) {
        return results1 + results2;
    });
},

drawGraph: function(stats) {
    // do stuff with the stats
},

// lower down...
this.loadData().then(this.drawGraph);

如果第二个电话不依赖于第一个电话,您可以使用promise.all:

 <uses-permission android:name="android.permission.CAMERA"  tools:node="remove"  />
<uses-permission android:name="android.permission.READ_PHONE_STATE"  tools:node="remove"  />

答案 3 :(得分:0)

首先,您需要创建一个从AJAX调用中获取承诺的通用函数:

const ajaxPromise = url => 
 new Promise(resolve => 
        $.ajax({ dataType: 'json', url}).done(r => resolve(r); );               
    );

现在,您可以直接调用它们:

Promise.all(ajaxPromise(url1),
            ajaxPromise(url2))
  .then([results1, results2]) => results1 + results2);

或者如果你真的需要它们链接:

ajaxPromise(url1)
  .then(results1 =>
     ajaxPromise(url2)
      .then(results2 => results1 + results2));