如何通过异步xmlhttprequest响应设置变量

How to set a variable via asynched xmlhttprequest response

本文关键字:设置 变量 响应 xmlhttprequest 何通过 异步      更新时间:2023-09-26

如果我发出同步请求,我试图实现的目标可以很容易地完成,但由于它已被弃用,我现在正在更新我的脚本,以正确使用异步调用,这样当其他方法停止工作时,脚本就可以继续工作。

我目前使用的代码如下:

function GET(a) {
  var request = new XMLHttpRequest(),
    data;
  request.open("GET", a, false);
  request.onreadystatechange = function () {
    if(4 == request.readyState) data = request.responseText;
  };
  request.send();
  return data;
}
function getObject(a) {
  var constructor = {};
  constructor.property1 = 'something1';
  constructor.property2 = 'something2';
  constructor.property3 = 'something3';
  constructor.property4 = true;
  if(a && a.attribute === null) constructor.property5 = GET('/url-location');
  return constructor;
}
var object = getObject(a);
if(object.property5) doSomethingWith(object);

正如您所看到的,请求是在运行时执行的,目的是为构造函数对象设置一个值。它之所以有效,是因为它是同步的,并且函数在继续之前等待响应,从而允许在返回对象之前设置一个值。

然而,当请求异步运行时,情况不会发生同样的情况,因为函数在不等待响应的情况下继续运行。

我的问题很明显;是否可以用异步请求复制相同的行为?如果没有,那么我怎么能在不做太多修改的情况下实现同样的结构呢?我的意思是,构造函数对象的创建需要以我所呈现的方式来创建;调用getObject后按顺序设置多个属性,并在完成时返回。

我不能使用库,所以没有jQuery、Node等。我也在避免定时/循环函数。

还有一个我几乎忘记的细节:GET函数被另一个结构不同但目标相似的函数使用,所以这并不像更改GET函数以仅使用我提供的示例那么简单。

将回调函数传递到GET中,并调用它:

function GET(a, callback) {                                     // <== Change here
  var request = new XMLHttpRequest();                           // <== No need for `data`
  request.open("GET", a, true);
  request.onreadystatechange = function () {
    if(4 == request.readyState) callback(request.responseText); // <== Change here
  };
  request.send();
}

用法(还有回调,我没有调用更改,它们就像上面一样):

function getObject(a, callback) { 
  var constructor = {};
  constructor.property1 = 'something1';
  constructor.property2 = 'something2';
  constructor.property3 = 'something3';
  constructor.property4 = true;
  if(a && a.attribute === null) GET('/url-location', function(data) {
    constructor.property5 = data;
    callback(constructor);
  });
}

用法:

getObject(a, doSomethingWith);

或者,如果你真的需要object变量:

var object;
getObject(a, function(data) {
    object = data;
    doSomethingWith(object);
});

但是注意object将是undefined直到回调发生(例如直到XHR调用完成)。

另一种方式是承诺,但它仍然涉及回调,只是一种不同的(可以说更强大/更方便的)链接方式。