简体   繁体   中英

$.when().then() nested as a callback function

I have a function, query1() , containing a $.when() promise which I would like to use as the argument for a parent $.when() promise. The value returned from query1() should be passed down the line, as in the variable b . The problem is that the parent $.when resolves before the child, but it needs to wait.

What's the best way to correct the order, so that the parent waits for the child to resolve?

$.when(query1(a))
.then( function(b) {

   console.log("step 3");

   return query2(b);

})
.then( function(c) {

   console.log("step 6")

});


function query1(a) {
   console.log("step 1");

   $.when(asynchronous_function())
   .then( function(data) {
      
      console.log("step 2");
      return data;

   });
}

function query2(b) {
   console.log("step 4");

   $.when(asynchronous_function())
   .then( function(data) {
      
      console.log("step 5");
      return data;

   });
}

Console will read:


Step 3
Step 6
Step 1
Step 2
Step 4
Step 5

I'm trying to avoid the "pyramid of death" thing here, to make my code both more readable and modular.

Thank you for your help.

The value returned from query1() ...

That's what is missing: query1() has no return statement. The one in the then callback is a return statement for that callback function, not for query1() . Each function that needs to return something significant needs its own return statement.

So add it both in query1 and query2 .

 $.when(query1(1)).then( function(b) { console.log("step 3", b); return query2(b); }).then( function(c) { console.log("step 6", c) }); function query1(a) { console.log("step 1", a); return $.when(Promise.resolve(42*a)).then( function(data) { console.log("step 2", data); return data; }); } function query2(b) { console.log("step 4", b); return $.when(Promise.resolve(b*144)).then( function(data) { console.log("step 5", data); return data; }); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Having said that, there is no reason to call $.when when you are going to pass it a single promise object. That promise can be used directly to call then on it.

That would lead to this:

 query1(1).then( function(b) { console.log("step 3", b); return query2(b); }).then( function(c) { console.log("step 6", c) }); function query1(a) { console.log("step 1", a); return Promise.resolve(42*a).then( function(data) { console.log("step 2", data); return data; }); } function query2(b) { console.log("step 4", b); return Promise.resolve(b*144).then( function(data) { console.log("step 5", data); return data; }); }

Nowadays there is no good reason anymore to use jQuery deferred objects for working with promises. Since ECMA Script 2015 JavaScript has the native promises.

You can even use async / await syntax:

 (async () => { const b = await query1(1); console.log("step 3", b); const c = await query2(b); console.log("step 6", c) })(); async function query1(a) { console.log("step 1", a); const data = await Promise.resolve(42*a); console.log("step 2", data); return data; } async function query2(b) { console.log("step 4", b); const data = await Promise.resolve(b*144); console.log("step 5", data); return data; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM