函数执行顺序错误

Functions executing in wrong order

本文关键字:错误 顺序 执行 函数      更新时间:2023-09-26

我的问题有点难以解释,但我会尽力的。我有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])输出之前打印在日志中。有人知道我如何使getQueueData()完全执行之前去'shown.bs.tab'事件吗?

哈哈!

对于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的回调在必要时发生。

更多信息,请阅读这篇很棒的指南

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();
    });
}