首页 > 解决方案 > Javascript在函数中同步运行异步方法

问题描述

我想创建一个监听函数来监听全局变量的变化。用例是,当我进行 ajax 调用时,我将isAjaxDone变量标记为false,一旦完成,然后将其标记为true. 因此,一旦检测到isAjaxDoneis ,侦听器就会处理某些内容true

我试过了asyc ... awaitPromise但我仍然无法实现我想要的。整个方法仍然在外面异步运行,除了asyc ... await&里面的方法Promise

这是我尝试过的:

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"
    }
  }
}

执行:

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

当我调用时isAjaxDone,它会返回一个 Promise 函数而不是布尔值。

我不喜欢使用Promise...then,因为我写的函数被认为是库,我不希望用户在里面包装一堆代码,then因为它会给用户代码结构带来一些问题。也一样Callback

我想让它等到返回超时或仅返回布尔值,请告知。

标签: javascript

解决方案


您可以执行以下操作:

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;
});

当然,我只会创建一个 post 函数,并在一切完成后执行一个函数,例如:

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;
}

现在您可以重用:

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
});

推荐阅读