我正试图找出一种检查某些异步调用是否“准备就绪”的好方法。我有一些运行$ .ajax的函数,并且在回调函数中将全局范围内的布尔变量设置为true(以及其他一些东西)。在ajax调用之前,该布尔变量为false。
我想要另一个检索“其他东西”的函数。由于ajax调用是异步的,显然我不能立即去检索它,因为它可能还不存在。这就是这个布尔变量的来源。我想我可以检查每100毫秒布尔值是否为真,当它出现时,然后检索并返回“其他东西”。
代码方面,它看起来像这样:
window.FOO = window.FOO || {};
;(function() {
var isReady = false;
var stuff;
$.ajax({
...
success: function(data) {
stuff = data;
isReady = true;
}
})
FOO.getStuff = function() {
// How to check if it's "ready"?
};
}
... (somewhere else)...
var stuff = FOO.getStuff();
我已经尝试了以下FOO.getStuff
无效,因为(我认为)setTimeout是异步的:
FOO.getStuff = function() {
if (isReady) {
return stuff;
}
var theStuff;
setTimeout(function() {
theStuff = FOO.getStuff();
}, 100);
return theStuff;
};
使用控制台,我可以看到它正在做正确的事情......但是第一个FOO.getStuff
调用会在后续调用之前返回。
有更好的方法吗?
编辑:为了澄清,我希望ajax调用保持异步。我完全可以使用同步的getStuff()调用,因为ajax调用会非常快,并且在大多数情况下,getStuff()将在稍后调用(在使用后执行某些操作)。
答案 0 :(得分:1)
根据你的意见,我有你的答案。要解决异步问题,我们应该执行异步操作。
var stuff;
var stuffQueue = [];
$.ajax({
success: function(data) {
stuff = data;
if( stuffQueue.length > 0 ){
for(var i in stuffQueue){
var callback = stuffQueue[i];
callback(stuff);
}
stuffQueue = [];
}
}
});
function getStuff(callback){
//stuff has been loaded?
if( stuff ){
callback(stuff);
}else{
stuffQueue.push(callback);
}
}
要调用内容:
var something = getStuff(function(stuff){
console.log(stuff);
});
这应该可以解决您的使用案例。让我告诉你更多信息,我有一个JavaScript模板引擎,还没有开源,但我一直在专业项目中使用,我只用一个HTTP请求加载所有模板,我发出请求async:false因为它是一个项目的依赖性。
有些读法说异步虚假是邪恶的,我不相信,邪恶就是用错了。加载模板文件主文件是async:false可以工作的一个很好的例子。
另外,我建议你阅读有关promisses: http://www.html5rocks.com/en/tutorials/es6/promises/
答案 1 :(得分:0)
var isReady = true;
$.ajax({
beforeSend: function() {
isReady = false;
},
success: function(data) {
isReady = true;
$(document).trigger('display-stuff', data);
}
});
Foo.getStuff = function(data) {
if (!isReady) {
$(document).one('display-stuff', Foo.getStuff);
return;
}
// do something
};