0

So I wrote javascript about promise. I made two promise inside a for loop like this:

for(let i=0; i<globalName.length; i++ ){                
    let debug = globalName[i];

    var promise1 = new Promise(function(resolve,reject){                    
        var j = searchStart(startT,debug);

        resolve(j)

    }).then(function(result){
        sxx = result;                   
    }); 


    var promise2 = new Promise(function(resolve,reject){
        var k = searchEnd(endT,debug);

        resolve(k);

    }).then (function(result){
        syy = result;                   
    });

    Promise.all([promise1, promise2]).then(function(values) {

        let localed = [];
        entry[i] = sxx;
        exit[i] = syy;

        localed.push({
            "name" : debug,
            "first" : entry[i],
            "last" : exit[i]
        });
        xtable.rows.add(localed).draw();                    
    });             
}

In each promise, I call function searchStart(startT,debug) and searchEnd(endT,debug), which within each function, I also wrote promise script that return value from an API (ready called API from a device, when I called it, returns JSON data). JSON data works fine, and I can access it with my function and returned some intended value.

With the Promise.all when my function returns value, I write the data into table provided from DataTables. But of course because the function run when two promises above resolved, it can only write to my table with every each row of data.

Now, what I want to ask is, can I somehow manage to write all data first, and after the data is complete I call other function to write to table?

g_pratama
  • 3
  • 2
  • yes, save each promise1 and promise2 in an array .. but why are you using promises since there doesn't seem to be anything asynchronous happening – Bravo Oct 30 '18 at 05:00
  • @bravo actually the function for call API, it return with different time required to complete the task, since it contains lot of data inside JSON object, so I thought I should use promises to wait each calling progress – g_pratama Oct 30 '18 at 07:54
  • if `searchStart` and `searchEnd` are asynchronous, you're doing it wrong - you're not waiting for those to complete, you're just resolving with whatever they return .... oh ... they return a Promise? No need for Promise constructor then – Bravo Oct 30 '18 at 07:58

2 Answers2

0

You can .map each debug to its associated Promise.all, so that you have an array of Promise.alls. Then, after calling Promise.all on that array, you can add all rows at once.

Note that since searchStart and searchEnd look to already return Promises, there's no need for the explicit Promise constructor antipattern - simply use the existing Promise alone. Also, by returning a value inside a .then, you can avoid having to use outer variables like sxx, syy, entry[i], and exit[i]:

const promiseAlls = globalName.map((debug, i) => {
  return Promise.all([
    debug, // see below for note
    searchStart(startT, debug),
    searchEnd(endT, debug)
  ]);
});
Promise.all(promiseAlls).then((allArrs) => {
  allArrs.forEach(([
    name, // this is the same as the "debug" variable above
    first, // this is the same as `entry[i]`, or `sxx`, in your original code
    last // this is the same as `exit[i]`, or `syy`, in your original code
  ]) => {
    const localed = [{ name, first, last }];
    xtable.rows.add(localed).draw(); 
  });
});

The debug is used in the initial Promise.all even though it's not a Promise so that it can be passed along and used with its other associated values, once they've been resolved.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
0

I am not clear about what you want, but I have two answers which may help you Solution 1: It will solve each promise at a time then proceed for next

function searchStartAndEnd(flag = false, date, debug){
  return new Promise((resolve, reject)=>{
        var j;
        if(flag){
            j = searchStart(date, debug);
        }else{
            j = searchStart(date, debug);
        }
       resolve(j)
  })
}

for(let i=0; i<globalName.length; i++ ){                
    let debug = globalName[i];
    sxx = await searchStartAndEnd(true, startT, debug);
    syy = await searchStartAndEnd(false, endT, debug) ;  
    localed.push({
        "name" : debug,
        "first" : sxx,
        "last" : syy]
    });
    xtable.rows.add(localed).draw();
}

solution 2: It will solve all promise parallel then do move to the next task, then move next iteration
function searchStartAndEnd(flag = false, date, debug){
  return new Promise((resolve, reject)=>{
        var j;
        if(flag){
            j = searchStart(date, debug);
        }else{
            j = searchStart(date, debug);
        }
       resolve(j)
  })
}
 for(let i=0; i<globalName.length; i++ ){                
    let debug = globalName[i];
    sxx = await ;
    [sxx, syy] = await Promise.all([searchStartAndEnd(true, startT, debug), 
    searchStartAndEnd(false, endT, debug)])  
    localed.push({
        "name" : debug,
        "first" : sxx,
        "last" : syy]
    });
    xtable.rows.add(localed).draw();
 }
Biplab Malakar
  • 750
  • 6
  • 11