如何处理$ .Deferred中的嵌套调用

时间:2019-01-08 05:33:27

标签: javascript jquery

我正在使用jQuery的$.Deferred函数来处理多个嵌套调用。当前代码无法正常工作。我想在所有请求完成后触发一个函数。但目前在两次请求后到达console.log

function ajac(){
  var dfd = $.Deferred();
  var api = require('modules/api');
  for(var i=0;i<2;i++){
      api.request("GET","https://t25501-s39032.sandbox.mozu.com/events/priceadjustment").then(function(res) {
          api.request("GET","https://t25501-s39032.sandbox.mozu.com/events/priceadjustment").then(function(res) {
            dfd.resolve();
          });
      });
  }
  return dfd.promise();
}
$.when(ajac()).then(function(){
  console.log("reached");
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

3 个答案:

答案 0 :(得分:0)

您遇到的问题是,即使循环表明您打算跟踪多个延迟,您最终还是要定义,解决并返回延迟的$.when希望将多个延期作为单独的参数传递。为了使该示例起作用,我包括了一个从jQuery文档中提取的模拟asyncEvent函数。请参见下面的代码片段,以查看一切正常:

function asyncEvent() {
  var dfd = jQuery.Deferred();
 
  // Resolve after a random interval
  setTimeout(function() {
    dfd.resolve( "hurray" );
  }, Math.floor( 400 + Math.random() * 2000 ) );
   
  // Return the Promise so caller can't change the Deferred
  return dfd.promise();
}

function makeAjac(i) {
    var dfd = $.Deferred()
    asyncEvent().then(function(res) {
        asyncEvent().then(function(res) {
          console.log(`request pair ${i} complete.`);
          dfd.resolve();
        });
    });
    return dfd.promise();
}

function ajac() {
  var promisesArray = [];
  for(var i=0;i<2;i++){
    promisesArray.push(makeAjac(i));
  }
  return promisesArray;
}

$.when.apply($, ajac()).then(function(){
  console.log("reached");
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

我们在这里所做的是将在for循环内执行的代码放入其自己的函数makeAjac中,该函数通过循环返回其特定迭代的承诺。然后,在原始的ajac中,我们将那些返回的承诺放入promisesArray中,然后从ajac返回。最后,我们利用.apply来将数组中的promise作为$.when的单独参数传递。从运行该代码段可以看到,此功能可以按预期运行。

答案 1 :(得分:-1)

单个承诺只能被解决或拒绝一次。您需要返回不同的承诺才能解决所有的承诺。像这样:

function ajac(){
  var allPromises = [];
  var api = require('modules/api');
  for(let i=0;i<2;i++){
      let dfd = $.Deferred();
      api.request("GET","https://t25501-s39032.sandbox.mozu.com/events/priceadjustment").then(function(res) {
          api.request("GET","https://t25501-s39032.sandbox.mozu.com/events/priceadjustment").then(function(res) {
            dfd.resolve();
          });
      });
      allPromises.push(dfd.promise());
  }
  return Promise.all(allPromises);
}
$.when(ajac()).then(function(){
  console.log("reached");
})

一种更好的方法是使用Observables(例如:RxJS)

您可以参考以下答案以了解词素与可观察变量之间的差异:https://stackoverflow.com/a/37365955/6080889

答案 2 :(得分:-1)

您可以尝试以下方法:

您需要浏览以下链接:http://localhost:4000/about/investors/key-dates-and-events-details?year=2017#q1

var callAPI=function(){
const promise = new Promise((resolve, reject) => {
         var api = require('modules/api');
         resolve(api.request("GET","https://t25501-s39032.sandbox.mozu.com/events/priceadjustment"));
  });
return promise;
}    


function getInfo(){
    const promise = new Promise((resolve, reject) => {
            var allPromise=[];
            for(var i=0;i<2;i++){
                  allPromises.push(callAPI());
            }
                  return Promise.all(allPromises);
     });
return promise;
}

getInfo().then((result)=>{
       console.log("reached",result);
});