Search code examples
javascriptjquerypromisecallbacknested

Javascript, jQuery: How to write nested Promises in LOOPS in more LOOPS?


What kind of JavaScript or jQuery construction of callbacks and/or promises can be used in such a case? Can it be done at all?

I tried this working minimal example (/vocab and /vocab2 are REST services):

 "use strict";

 window.onload = function(e)
 { 
    console.log("HELLO WORLD");

    var promises = [];
    promises.push(doxxx());

    Promise.all(promises).then(
       dozzz();
    );
 }

function doxxx()
{
   console.log('doxxx CALLED');
    $.ajax({
       url: '/vocab', 
       type: 'POST',
       dataType: 'json',
     success: function(result) 
     {
         console.log(result.data);
         var promises = [];
         $.each(result.data,  function( index, value )
         {
            promises.push(doyyy(value[3]));
         });

         return Promise.all(promises);
      }
  });
 }

 function doyyy(german)
 {
    console.log('doyyy CALLED');
   $.ajax({
      url: '/vocab2', 
      type: 'POST',
     data: {german : german},
     dataType: 'json',
     success: function(result) 
     {
       return new Promise(function(myResolve, myReject) 
       {
         console.log(result.data);
       })
    }
 });
}

function dozzz()
{
   console.log("END");
}

I expected all nested promises to be fullfilled before dozzz() is called and "END" is printed to the console.

But it was not working. It printed "END" before "doxxx CALLED" and "doyyy CALLED."

UPDATE

I tried the answer from Alexander Nenashev. It worked. Thank you.

Console output in correct order


Solution

  • Use async/await it will make the code more manageable, readable and maintainable.

     "use strict";
    
     window.onload = async function(e)
     { 
        console.log("HELLO WORLD");
        await doxxx();
        dozzz();
    }
    
    async function doxxx()
    {
       console.log('doxxx CALLED');
       
       const result = await $.ajax({
           url: '/vocab', 
           type: 'POST',
           dataType: 'json',
       });
       
       console.log(result.data);
       
       return Promise.all($.map(result.data, (_, value) => doyyy(value[3])));
     }
    
     async function doyyy(german)
     {
        console.log('doyyy CALLED');
        
        const result = await $.ajax({
          url: '/vocab2', 
          type: 'POST',
         data: {german : german},
         dataType: 'json',
      });
     
      console.log(result.data);
    }
    
    function dozzz()
    {
       console.log("END, but not the END");
    }