如果我发出同步请求,我可以轻松完成我想要实现的目标,但由于它已被弃用,我现在正在更新我的脚本以正确使用异步调用,以便当其他方法停止工作时脚本继续工作。
我目前使用的代码如下:
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函数那样简单,只需使用我提供的示例
答案 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,但它仍然涉及回调,只是一种不同的(可以说是更强大/更方便)链接它们的风格。