1

The scenario is like this, I get a get request and it triggers a function which returns a Promise (promise1), and the Promise returning function itself has a chain of promises. Now I do not want to wait for the chain to be over before sending the response to the front end, but want to resolve somewhere in the middle.

Now the rest of the question is put as a comment in the code, where it makes more sense.

app.get('/data', (req, res)=>{

    promise1()
    .then(result=>{     
        res.status(200).send({msg:result});     
    })
    .catch(result=>{
        res.status(400).send({msg:"Error"});
    })
})

let promise1 = ()=>{
    return new Promise((resolve, reject)=>{
        promise2()
        .then(result=>{
            resolve(result);
        /*What I want here is, just after the promise2 is resolved I want 
        to send the result back to the get router, so I can give quick response
        and continue the slow processing in the backend which is promise3, but this
        does not work as expected, I do not get the result in the router until promise3 is 
        resolved. But I do not want that. So any suggestions on how to achieve that.
        */

            return promise3()           
        })
        .then(result=>{
            console.log("Done");            
        })
        .catch(err=>{                       
            console.log(err);           
        })      
    })
}

let promise2 = ()=>{
    return new Promise((resolve, reject)=>{ 
        resolve("Done");        
    })
}

let promise3 = ()=>{
    return new Promise((resolve, reject)=>{     
        //Slow Async process
        resolve("Done");        
    })
}

Was able to do this by putting promise3 in setTimeout but I am not sure if that is the correct way.

Please ignore any syntactical mistake, this is just to give the idea of the question.

Also, I am not sure if this is the correct way of doing this - correct me if I am wrong.

Sinandro
  • 2,426
  • 3
  • 21
  • 36
utkarsh tyagi
  • 635
  • 1
  • 9
  • 27
  • You can pass res to the promise1 function and then use res.send inside of it or inside of other embedded functions. – Artem Arkhipov Jul 16 '17 at 12:14
  • 1
    @Tamango no, that's absolutely not what should be done. The promise abstraction is there for a reason: not needing to pass such a callback – Bergi Jul 16 '17 at 12:15
  • 1
    Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Jul 16 '17 at 12:17
  • @Bergi, sure, but he needs to send response at some middle point of the whole process. How to do that using native promises without passing some variable/method inside? Another solution is to use bluebird library. – Artem Arkhipov Jul 16 '17 at 12:19
  • @Tamango There's no "whole process", there are two processes, and the one that creates the response should resolve immediately. – Bergi Jul 16 '17 at 12:33

1 Answers1

4

Oops, looks like I prematurely closed as a duplicate of How to properly break out of a promise chain?. What you actually wanted is hidden in the comment in the source code:

Just after the promise2 is resolved i want to send the result back to the get router so i can give give quick response and continue the slow processing in the backend which is promise3, but

return promise3()

does not work as expected, i do not get the result in the router until promise3 is resolved.

That's more like Can I fire and forget a promise in nodejs (ES7)? - yes, you can. You'll just want to return the result that you want to send back from the function so that the promise chain continues with that and can send it right away. The slow backend processing would be started by calling it, but not having it awaited by returning it into the chain:

function promise1() {
    return promise2().then(result => {

        // kick off the backend processing
        promise3().then(result => {
            console.log("Backend processing done");
        }, err => {
            console.error("Error in backend processing", err);
        });
        // ignore this promise (after having attached error handling)!

        return result; // this value is what is awaited for the next `then` callback
    }).then(result => {
        // do further response processing after having started the backend process
        // before resolving promise()
        return response;
    })
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375