0

I have 2 async calls

function async1() {
  return $j.post('/call1', JSON.stringify({
    id: my_id
  }), function(response) {
    if (response.success) {
      // resolve
    } else {
      // reject
    }
  });
}

function async2() {
  return $j.post('/call2', JSON.stringify({
    id: my_id
  }), function(response) {
    if (response.success) {
      // resolve
    } else {
      // reject
    }
  });
}

From a main() function I need to call async1() first and if it is successful, async2() will be called.

I intend to return a promise from main(). My main concern is that I need to explicitly resolve or reject according to the responses. Can anyone show me how to go about it using promises / deferred?

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Vivek
  • 341
  • 1
  • 5
  • 15

3 Answers3

0

Could go like this:

function async1() {

  return new Promise((resolve, reject) => $j.post(
      '/call1',
      JSON.stringify({
        id: my_id
      }),
      function(response) {
        if (response.success) {
          resolve( /*pass whatever*/ )
        } else {
          reject( /*pass whatever*/ )
        }
      });
  }
}

function async2() {

  return new Promise((resolve, reject) => $j.post(
      '/call2',
      JSON.stringify({
        id: my_id
      }),
      function(response) {
        if (response.success) {
          resolve( /*pass whatever*/ );
        } else {
          reject( /*pass whatever*/ )
        }
      });
  }
}

function main() {
  async1().then(async2).then((success) => console.log(success)).catch(err => console.error(err));
}
Karen Grigoryan
  • 5,234
  • 2
  • 21
  • 35
  • 1
    Code dumps are not **useful** answers, and if you're going to use `new Promise` when you already have a thenable, you'll need to explain why it's better than using the thenable. – T.J. Crowder Feb 20 '18 at 11:46
  • 1. deferreds are (antipattern)[https://stackoverflow.com/questions/30750207/is-this-a-deferred-antipattern], jquery promise implementation is diverging from the standards and dying out. 2. Regarding code dump, generally I agree, but if the code is self explicative I'd still be fine with it. – Karen Grigoryan Feb 20 '18 at 12:02
0

You call async1() first, and at the successful response of async1() you do async2() function. Like this:

function async1() {

  return $j.post(
        '/call1',
        JSON.stringify({id: my_id}),
        async2(response)    // <-- Replace function(response){} to this.
  });

}

And then on async2 function:

function async2(dataAsync1) {
  var data = dataAsync1;  //Response from previews Ajax call...
                          //TODO: Handle this
  return $j.post(
    '/call2',
    JSON.stringify({id: my_id}),
    function(response) {
        if (response.success) {
            // resolve
        }
        else {
            // reject
        }
   });
}
0

My main concern is , i need to explicitly resolve or reject according to the responses.

Good concern: No, you don't. Just use the results you're given by the promise from jQuery's post.

Since you're using jQuery v1.x, I'll just note that its Deferred object is not Promises/A+ compliant. You may or may not care about that. I'll assume you're using v1.8 or later, though.

So if you're okay with using jQuery's non-Promises/A+-compliant Deferred and promise, then just return the result of post.

I'll stick with ES5 syntax, since you're using jQuery v1.x and I'm guessing you're not transpiling, etc.

function async1(my_id/* I assume it's a parameter?*/) {
    return $j.post(
        '/call1',
        JSON.stringify({id: my_id})
    );
}

function async2(my_id/* I assume it's a parameter?*/) {
    return $j.post(
        '/call2',
        JSON.stringify({id: my_id})
    );
}

...and in main, use those "promises":

function main(some_id) {
    return async1(some_id).then(function(result1) {
        return async2(some_id).then(function(result2) {
            return [result1, result2];
        });
    });
}

That example has main returning a promise of an array, where the first entry in the array will be the result from async1 and the second is the result from async2 (or where it rejects because one of them failed). You can tweak that as you like, though, by changing the return in the second then handler.

If you want main to return a native promise instead (using a polyfill if necessary), I'd probably convert to native promises early by giving myself a wrapper for post that provides a native promise:

function postPromise() {
    var args = Array.prototype.slice.call(arguments);
    return new Promise(function(resolve, reject) {
        $j.post.apply($j, args)
            .done(resolve)
            .fail(function(jqXHR, textStatus, errorThrown) {
                if (errorThrown) {
                    reject(errorThrown);
                } else {
                    reject(new Error(textStatus)); // or whatever
                }
            });
    });
}

then

function async1(my_id/* I assume it's a parameter?*/) {
    return postPromise(
        '/call1',
        JSON.stringify({id: my_id})
    );
}

function async2(my_id/* I assume it's a parameter?*/) {
    return postPromise(
        '/call2',
        JSON.stringify({id: my_id})
    );
}

...and in main, use those "promises":

function main() {
    return async1("the-id").then(function(result1) {
        return async2("the-id").then(function(result2) {
            return [result1, result2];
        });
    });
}

That has the advantage (?) of working with jQuery < v1.8.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Basically 'async1' can succesfully complete and according to the value of certain data got as response , i need to reject or resolve . How is that possible here? – Vivek Feb 20 '18 at 12:13
  • @Vivek: Sorry, I'm afraid that's not really clear. Do you want to call `async2` even if `async1` fails? *Only* when it fails? Only when it succeeds? – T.J. Crowder Feb 20 '18 at 12:18
  • Only when async1 succeeds should async2 be called. The caveat here is the success condition. If i got succesful response say `responseData` and if `responseData.someVariable == false` , then async2 should not be called. – Vivek Feb 20 '18 at 12:23
  • @Vivek: Just put that condition inside the `then` handler on the call from `async`, and either return something else or return the result of calling `async2`. – T.J. Crowder Feb 20 '18 at 12:46