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

时间:2014-11-08 19:44:04

标签: javascript

如果我发出同步请求,我可以轻松完成我想要实现的目标,但由于它已被弃用,我现在正在更新我的脚本以正确使用异步调用,以便当其他方法停止工作时脚本继续工作。

我目前使用的代码如下:

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函数那样简单,只需使用我提供的示例

1 个答案:

答案 0 :(得分:2)

将回调函数传递到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调用完成)。

另一种方法是使用promises,但它仍然涉及回调,只是一种不同的(可以说是更强大/更方便)链接它们的风格。