在另一个延期中返回延期承诺

时间:2015-04-12 15:47:05

标签: javascript jquery promise jquery-deferred

请考虑以下事项:

function foo(){
  // Returns the jQuery deffered below.
    var urlToUse;
     $.ajax({
          url:'someUrl',
          success:function(res){urlToUse= res;}
     }).then(function(){
       return  $.ajax({url:urlToUse,
             success:function(){
                //Do something 
             }
         }); // I want to return this deffered object!
     })
}

有没有办法在承诺中归还承诺?

2 个答案:

答案 0 :(得分:3)

你刚刚做到了。 jQuery then中可能会发生三件事:

如果您没有向then返回任何内容,则下一个链接将使用与之前附加的then相同的值解析。

$.ajax(...)
  .then(function(result){ // result = 5
    // This block executes when the first AJAX resolves
    // Do nothing
  })
  .then(function(result){ // result = 5
    // This block executes right after the previous `then`
    // and still uses the same resolved value
  });

如果你返回一个承诺(比如来自jQuery ajaxDeferred),下一个被链接的then将在返回的承诺解析时解决。< / p>

$.ajax(...)
  .then(function(firstAjaxResult){
    // This block executes when the first AJAX resolves

    // Return a promise
    return $.ajax(...);
  })
  .then(function(secondAjaxResult){
    // This will resolve when the second AJAX resolves
  });

如果您返回除承诺之外的任何内容,则下一个链接将解析为前一个then返回的值而不是原始值。

$.ajax(...)
  .then(function(result){ // result = 5
    // This block executes when the first AJAX resolves

    // Return a modified result
    return result * 3;
  })
  .then(function(newResult){ // newResult = 15
    // This block executes right after the previous `then`
    // but resolves with the modified value
  });

答案 1 :(得分:2)

您只需要返回外部$ .ajax链返回的保证。将$.ajax...替换为return $.ajax...

您实际上可以更简洁地写出这一点,因为.then可以替代使用success:回调

function foo(){
     // | This return is all you need to add to make your current code work      
     // V
     return $.ajax({url:'someUrl'}).then(function(res) {
         var urlToUse = res;
         return $.ajax({url: urlToUse});
     }).then(function(secondRes) {
         //Do something
         return "Got: " + secondRes;
     });
}

然后您可以将其用作:

foo().then(function(finalRes) {

}, function(someError) {

});