简体   繁体   中英

Conditional Promise Chaining

I get an array of args as an argument, and then I make lots of server calls based on the algo below.

  1. Post to endpoint /abc with args array as data.
  2. Iterate over args array,

    a. Pull 3 at a time and send 3 Get calls to endpoint /pqr

    b. Once 3 calls in step '2.a' succeeds send 3 Post calls to endpoint /def

    c. Collect responses from step '2.a' server call and push it in an array.

    d. Repeat step a,b,c till args length.

Code Snippet for the entire process is given below, execution starts at function execute(args).

 import Promise from 'bluebird'; import request from 'superagent'; // sends a post request to server const servercall2 = (args, response) => { const req = request .post(`${baseUrl}/def`) .send(args, response) .setAuthHeaders(); return req.endAsync(); }; // sends a post request to server const servercall1 = (args) => { const req = request .post(`${baseUrl}/abc`) .send(args) .setAuthHeaders(); return req.endAsync() .then((res) => resolve({res})) .catch((err) => reject(err)); }; async function makeServerCalls(args, length) { // convert args to two dimensional array, chunks of given length [[1,2,3], [4,5,6,], [7,8]] const batchedArgs = args.reduce((rows, key, index) => (index % length === 0 ? rows.push([key]) : rows[rows.length - 1].push(key)) && rows, []); const responses = []; for (const batchArgs of batchedArgs) { responses.push( // wait for a chunk to complete, before firing the next chunk of calls await Promise.all( ***// Error, expected to return a value in arrow function???*** batchArgs.map((args) => { const req = request .get(`${baseUrl}/pqr`) .query(args) // I want to collect response from above req at the end of all calls. return req.endAsync() .then((response) =>servercall2(args,response)); }) ) ); } // wait for all calls to finish return Promise.all(responses); } export function execute(args) { return (dispatch) => { servercall1(args) .then(makeServerCalls(args, 3)) .then((responses) => { const serverresponses = [].concat(...responses); console.log(serverresponses); }); }; } 

I am facing couple of issues

  1. 2.c seems not to be working fine "Collect responses from step '2.a' server call and push it in an array.". Error: expected to return a value in arrow function. What am I doing wrong here? Please note that at the end I care about the response from step 2.a only.
  2. Is this a right chaining or it can be optimized, based on the requirements mentioned above?
  3. Is there any other failure handling I have to do?

It might be this -- each item in batchArgs.map should be a Promise I think? Then Promise.all will wait for each to finish:

batchArgs.map((args) => {
    const req = request
        .get(`${baseUrl}/pqr`)
        .query(args)


    // Return promise here
    return req.endAsync()
        .then((response) =>servercall2(args,response))
        .then((res) => res);
})

You have a brick wall of text so its becoming a little hard to decipher what you're actually trying to achieve, but I will give my two cents on the code given.

 //Both server calls can be simplified.. no need to
 //wrap in another promise if one is being returned
 const servercall2 = (args, response) => {
       const req = request
            .post(`${baseUrl}/def`)
            .send(args, response)
            .setAuthHeaders();

        return req.endAsync();
};

    //Here... you return no value in the function passed to map, thus an 
    //error is being thrown. You need to return a Promise from here so that
    //it can be passed into Promise.all

        const allFinished = await Promise.all(
        batchArgs.map((args) => {
            const req = request
                .get(`${baseUrl}/pqr`)
                .query(args)

            // I want to collect response from above req at the end of all calls.
            return req.endAsync()
        })
       );
       allFinished.then(function(results){

       });

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