我的问题有点难以解释,但我会尽我所能。我有3个选项卡,其中一个默认是活动的。每次激活选项卡时,都会触发一个事件。但是,标签标题是在之前设置的功能中设置的。我的代码如下:
<script>
var queues = {};
$(document).ready(function(){
getQueueData();
$('.nav a[href="#queue1"]').tab('show');
});
function getQueueData(){
$.post('interface/getqueues.php', function(data){
var str = "#q";
for (var i=0; i<data.data.length; i++){
str += i;
$(str).text(data.data[i]["name"]);
queues[str] = data.data[i];
console.log(queues[str]);
str = "#q";
}
});
}
$('a[data-toggle="tab"]').on("shown.bs.tab", function(event){
console.log("HELLO WORLD!");
var elem = $(this).attr("id");
var id = "#"+elem;
console.log(queues);
});
</script>
现在,getQueueData()函数应该在shown.bs.tab
事件被触发之前执行。这对于后一个事件能够访问queues
对象中的值是必要的。实际上,当页面加载时,shown.bs.tab
函数首先执行,然后是getQueueData()。这意味着在shown.bs.tab
方法中,第一次queues
未定义。我知道这是因为HELLO WORLD和一个空对象在console.log(queues[str])
输出之前在日志中打印。有没有人知道如何在进入'shown.bs.tab'
事件之前完全执行getQueueData()?
答案 0 :(得分:4)
哈哈!
javascript异步领域初学者的常见问题。 :) 欢迎来到丛林伴侣。 ;)
这是魔术。移动$('.nav a[href="#queue1"]').tab('show');
内部$.post
功能。将它放在for
循环之后。 :)
function getQueueData(){
$.post('interface/getqueues.php', function(data){
var str = "#q";
for (var i=0; i<data.data.length; i++){
str += i;
$(str).text(data.data[i]["name"]);
queues[str] = data.data[i];
console.log(queues[str]);
str = "#q";
}
$('.nav a[href="#queue1"]').tab('show'); // << Triggre your show event here.
});
}
一切都会很好。
很快就会以解释的方式更新这个答案。 :)
==
编辑:
解释
getQueueData()
应该在shown.bs.tab
之前执行的问题已经完成。但是,在标签显示事件后,似乎会getQueueData()
执行。
这是为什么?
因为您在getQueueData()
内有异步调用。该脚本将对interface/getqueues.php
进行API调用,因为它是异步的,它的英雄性质会接管,它不会等到服务器响应。它继续执行并从函数getQueueData()
返回并继续并触发选项卡上的show事件(因为调用getQueueData
后的下一个语句是标签的show语句。
当服务器响应时,它将触发您在$.post
函数调用中指定的回调。
因此,当执行此回调时(从服务器收到响应后,选项卡上的show事件已经发生)。
这就是为什么在标签显示事件后getQueueData
似乎正在执行的原因。
但实际上,它会在标签显示事件之前执行,并且只要有必要就会发生$.post
的回叫。
有关详情,请参阅此awesome guide。
答案 1 :(得分:2)
post
是一种异步方法。这意味着它的结果不一定在调用之后得到。 Javascript是这样的语言,它不会等待异步方法的结果继续执行其余的代码。
因此,您必须自己同步代码。
您可以用于此目的的一件事是deferred object
。创建它时,它具有挂起状态。无论何时解决或拒绝该对象,您都会收到通知。
下面,请注意如何使用它。
deferred object
。
<script>
var queues = {};
var deferred = $.Deferred();
$(document).ready(function(){
getQueueData();
deferred.then(function() {
$('.nav a[href="#queue1"]').tab('show');
});
});
function getQueueData(){
$.post('interface/getqueues.php', function(data){
var str = "#q";
for (var i=0; i<data.data.length; i++){
str += i;
$(str).text(data.data[i]["name"]);
queues[str] = data.data[i];
console.log(queues[str]);
str = "#q";
}
deferred.resolve();
});
}