0

I want to create a listener function to listen changes of global variable. The use case is, when I made a ajax call, i flag isAjaxDone variable to false, once its done then flag it to true. So the listener will process something once detected the isAjaxDone is true.

i tried asyc ... await & Promise but i still can't achieve what i want. The entire method still run asynchronously outside, except the method inside asyc ... await & Promise.

Here is what i have tried:

var isAjaxDone = null
var timeout = 0
function listener(){
  let waiter = function(){
    return new Promise(resolve=>{
      setTimeout(() => {
        timeout += 1
        listener()
      }, 100);
    })
  }

  if(isAjaxDone) return true
  if(isAjaxDone === null) return false 
  if(isAjaxDone === false){
    if(timeout < 300){
      return waiter()
    }
    else{
      return "timeout"
    }
  }
}

Implementation:

function checker(){
  var ajaxStatus = listner()
  if(ajaxStatus){
    //...
  }
}

When i call isAjaxDone, it will return me a Promise function instead of boolean.

I prefer not to use Promise...then because the function i wrote is consider as library, I don't want the user wrap a bunch of code inside the then because it will caused some problem to user code structure. Same goes to the Callback.

I would like to let it wait until either return timeout or boolean only, please advise.

5
  • 2
    Why not just do the processing in a callback of the AJAX itself? For example, instead of doing isAjaxDone = true when the AJAX completes, just do your processing there instead. Commented Jan 28, 2019 at 3:27
  • You probably want to wrap the AJAX within a Promise, which resolves at the end of xhr.onload. Commented Jan 28, 2019 at 3:27
  • @Jerry do you have a variable scope problem? Variables have different values than what you want at the time the Ajax callback is being executed? Commented Jan 28, 2019 at 3:36
  • use Callback or Wrapping Ajax within a Promise caused my function less flexibility. I don't want wrap a bunch of code inside the then(data=>{ //...}) and i prefer "status/variable dependency" more than "function dependency", so user just have to check status instead of run the callback. Commented Jan 28, 2019 at 3:38
  • @ItayGrudev I prefer the listener() return boolean only. Commented Jan 28, 2019 at 3:40

2 Answers 2

1

You could do something like:

var xhr = new XMLHttpRequest;
xhr.open('POST', yourURLHere);
var promise = new Promise(function(resolve, reject){
  xhr.onload = function(){
    var o = JSON.parse(this.responseText); // should be `json_encode(['testProperty' => true])`ed response
    if(o.testProperty === true){
      resolve(true);
    }
    else{
      reject(false);
    }
  }
  xhr.send(formData); // you should get used to FormData
});
promise.then(function(resolveResult){
  yourGlobalVar = resolveResult;
});

Of course, I would just make a post function and execute a function when all is complete, like:

function post(url, formData, success, successContext){
  var xhr = new XMLHttpRequest;
  var c = successContext || this;
  xhr.open('POST', url);
  xhr.onload = function(){
    success.call(c, JSON.parse(xhr.responseText));
  }
  xhr.send(formData);
  return xhr;
}

Now you can reuse:

var fd = new FormData;
fd.append('output', true);
// PHP could look like
/* if(isset($_POST['output']) && $_POST['output'] === true){
     echo json_encode(['result' => true]);
   }
*/
post('someURL.php', fd, function(resultObj){
  globalVar = resultObj.result; // should be true since we sent that
});
Sign up to request clarification or add additional context in comments.

Comments

1

Why not use an AJAX API that is already awaitable like fetch? It is polyfillable.

const request = new Request('https://example.com', {method: 'POST', body: '{"foo": "bar"}'});
(async() => {
  const response = await fetch(request);
  return await response.json();
})()

1 Comment

I believe you forgot to declare response.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.