Search code examples
javascriptpromiseresolve

call two promises in the .then() clause in javascript


I have one promise which when it resolves, it will return "ResponseA" and in the .then() clause it is suppose to call two other promise and when they fulfill, it should print out the values(tgResponse.length and igResponse.length). But the problem is, it is always printing the value of last promise and skipping the first one which is console.log('igResponse', igResponse.length); Why this happens? and how can I make sure that it runs igApiPromise and tgApiPromise in parallel and prints the value for both of them. Thanks a lot for your help.

Here is my code:

new Promise((resolve, reject) => {
            /// do some stuff
                    resolve(responseA)
                }
            });
        }).then(ResponseA => {
            console.log(ResponseA.Values);
            igApiPromise(ResponseA.Values.token).then(igResponse => {
                console.log('igResponse', igResponse.length);
            });
            tgApiPromise(ResponseA.Values).then(tgResponse => {
                console.log('tgResponse', tgResponse.length);
            });  
         });

        let igApiPromise = token => {
            return new Promise(function (resolve, reject) {
                console.log('lotfan');
                xhttp.open("GET", "/api/igconfig", true);
                xhttp.setRequestHeader("Authorization", `Bearer ${token}`);
                xhttp.onload = function () {
                    if (this.status >= 200 && this.status < 300 && this.readyState == 4) {
                        resolve(xhttp.response);
                    } else {
                        reject({
                            status: this.status,
                            statusText: xhttp.statusText
                        });
                    }
                };
                xhttp.onerror = function () {
                    reject({
                        status: this.status,
                        statusText: xhttp.statusText
                    });
                };
                xhttp.send();
            });
        }

        let tgApiPromise = token => {
            return new Promise(function (resolve, reject) {
                xhttp.open("GET", "/api/tgApidata", true);
                xhttp.setRequestHeader("Authorization", `Bearer ${token}`);
                xhttp.onload = function () {
                    if (this.status >= 200 && this.status < 300 && this.readyState == 4) {
                        resolve(xhttp.response);
                    } else {
                        reject({
                            status: this.status,
                            statusText: xhttp.statusText
                        });
                    }
                };
                xhttp.onerror = function () {
                    reject({
                        status: this.status,
                        statusText: xhttp.statusText
                    });
                };
                xhttp.send();
            });
        }

Solution

  • Using Promise.all should look something like this:

    new Promise((resolve, reject) => {
          resolve(responseA)
        }
      });
    }).then(ResponseA => {
      const igPromise = igApiPromise(ResponseA.Values.token)
      const tgPromise = tgApiPromise(ResponseA.Values)
      return Promise.all([igPromise, tgPromise])
    }).then(responses => {
      const igResponse = responses[0]
      const tgResponse = responses[1]
      console.log('igResponse', igResponse.length)
      console.log('tgResponse', tgResponse.length)
    })
    

    Also, if you put your functions igApiPromise and tgApiPromise below the place you're using it, don't do variable assignment. Use the function syntax.

    function igApiPromise(token) {
    }
    

    I'm surprised you original code didn't throw an error.

    edit: Something is wrong with your api calls then. This barebones example with Promise.all works perfectly fine. it finished both in 6 seconds, as expected.

    function runProm() {
      return new Promise((resolve, reject) => {
          setTimeout(() => resolve('1000'), 2000)
      }).then(ResponseA => {
        const igPromise = igApiPromise(ResponseA)
        const tgPromise = tgApiPromise(ResponseA)
        return Promise.all([igPromise, tgPromise])
      }).then(responses => {
        const igResponse = responses[0]
        const tgResponse = responses[1]
        console.log('igResponse', igResponse)
        console.log('tgResponse', tgResponse)
      })
    }
    
    function igApiPromise(token) {
      return new Promise((resolve, reject) => {
        setTimeout(() => resolve('eyegApiPromise' + token), 4000)
      })
    };
    
    function tgApiPromise(token){
      return new Promise((resolve, reject) => {
          setTimeout(() => resolve('teegApiPromise' + token), 40)
      })
    }
    
    runProm()

    edit2:

    Did you declare xhttp in each respective function? This needs to be inside both .

    let igApiPromise = token => {
      var xhttp = new XMLHttpRequest()
    }