在另一个 deferred 中返回一个 deferred promise

Returning a deffered promise within another deffered

考虑以下因素:

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!
     })
}

有没有办法return承诺中的承诺?

你刚刚做到了。在 jQuery then:

中可能会发生 3 件事

如果您对 then 没有任何 return 任何东西,那么下一个链接将解析为与先前附加的 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
  });

如果你return一个承诺(比如来自jQueryajaxDeferred),下一个链接then 将在 returned 承诺解决时解决。

$.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
  });

如果您 return 除了承诺之外的任何东西,下一个链接将使用由前一个 then 编辑的值 return 解析,而不是原始值。

$.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
  });

您只需要 return 由外部 $.ajax 链 return 编辑的承诺。将 $.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) {

});