Home Wait for result of async operation
Reply: 3

Wait for result of async operation

user200300
1#
user200300 Published in 2018-01-11 08:12:11Z

I had such API for async requests

 request(pathParams, params, method, callback, error) {

        ...........

        return $.ajax({
            ...requestAttrs,
            url: url,
            data: params,
            xhrFields: {
                withCredentials: true
            },
            type: method,

            success: callback,
            error: error
        })
    }

But due to some requirements I need to change it to

request(pathParams, params, method, callback, error) {

            ...........
            someAsyncFunction(function(){
                return $.ajax({
                ...requestAttrs,
                url: url,
                data: params,
                xhrFields: {
                    withCredentials: true
                },
                type: method,

                success: callback,
                error: error
            })      

            })

        }

I hope you see my problem. In the previous case I was using the value returned from $.ajax call - for example because I would cancel those requests.

But now when I need to put my ajax function inside another async function, I can't return the $.ajax value like I did previously (because now I moved return inside someAsyncFunction).

Is there a way I could possibly first run that someAsyncFunction inside request, wait for its completion and then return $.ajax as I was doing before?

is something like stratified.js library usable for this?


someAsyncFunction is updateToken function from here. Basically I need to put what I had in request before, inside the success callback of updateToken - but the problem is I can't return the $ajax now as I did before.

Vignesh Raja
2#
Vignesh Raja Reply to 2018-01-11 08:37:39Z

You may want to do like this. Hope this fits your case. If I misunderstood it, pls ping in the comment.

Here, I just returned a string, you can edit to return the ajax request.

function someAsyncFunction(callback)
{
    //do something
    
    return callback();
}
function request(pathParams, params, method, callback, error) {
    return someAsyncFunction(function(){
            return "Ajax request";    
    });
}

console.log(request());

mersocarlin
3#
mersocarlin Reply to 2018-01-11 08:53:41Z

I took the liberty to change your code a little bit.

My approach is to separate code as much as possible so you don't get into the Callback Hell.

  1. Create someAsyncFunction and make whatever you judge necessary so then you can return its value

  2. Same applies to your ajax call. In case it needs the output from someAsyncFunction then it's very easy to send them as well

  3. Promise for the win! Chain all your calls and keep your code's flow :)

I'm using setTimeout so they look asynchronous

function someAsyncFunction() {
  return new Promise(resolve =>
    setTimeout(() => {
      console.log('-> someAsyncFunction has finished')
      
      const token = 'abc123'
      resolve(token)
    }, 1000)
  ) 
}

function executeAjaxRequest(pathParams, params, method, token) {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log('-> executeAjaxRequest has finished')
      resolve()
    }, 2000)
  })
}

function request(pathParams, params, method) {
  someAsyncFunction()
    .then((token) => executeAjaxRequest(pathParams, params, method, token))
    .then(() => console.log('-> end!'))
}

request('pathParams', 'params', 'method')

Sample code someAsyncFunction and keycloak thing :)

function someAsyncFunction() {
  return new Promise((resolve, reject) => {
    keycloak.updateToken(30)
      .success(resolve)
      .error(reject)
  })
}
Amadan
4#
Amadan Reply to 2018-01-12 07:50:47Z

OK, I see where your problem is. Apologies for not thinking it through. The jqXHR that $.ajax returns functions in two ways: both as a promise, and also as a handle where you can abort it before it is done. The first requires we return it, so that we can continue the promise chain. The second requires we retain it, so we can get at it outside the promise chain.

function authenticateWithKeycloak() {
  return new Promise((resolve, reject) => {
    keycloak.updateToken(30)
      .success(resolve)
      .error(reject)
  })
}    

function request(...) {
  let promise = authenticateWithKeycloak();
  promise.abort = () => { promise.aborted = true; }
  return promise.then(authenticated => {
    if (!promise.aborted) {
      let xhr = $.ajax({...});
      promise.abort = () => xhr.abort();
    }
    return promise;
  })
}

let reqPromise = request(...);
reqPromise.then(...);
reqPromise.abort();

EDIT: allowed aborting before AJAX.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.338108 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO