suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Warum ist das Entfernen von jQuery nicht synchron?

Auf der Seite gibt es eine Schaltfläche wie folgt

<button onclick="index.testClick()" >开始</button>

Das dieser Seite entsprechende JS-Skript lautet wie folgt

var index = {
    testClick: function () {
        index.createBtn(function() {
            index.sleep(10000);
        });
    },
    sleep: function (n) {
        var start = new Date().getTime();
        while (true) {
            if(new Date().getTime() - start > n) 
                break;
        } 
    },
    createBtn: function (func) {
        var    button = $('<button>测试</button>');
        button.bind("click",function(){
            button.remove();
            func();    
        });    
        $('body').prepend(button);
    },
};

Warum ruht die Testschaltfläche nach dem Klicken auf die Startschaltfläche und dann auf die Testschaltfläche tatsächlich (ich habe es bei der synchronisierten $.ajax-Anfrage bemerkt, die hier mit einer Schleife simuliert wurde), bevor sie entfernt wird? Nur wenn wir den Schlaf in setTimeout einschließen, können wir den gewünschten Effekt erzielen ...?

phpcn_u1582phpcn_u15822748 Tage vor600

Antworte allen(3)Ich werde antworten

  • 某草草

    某草草2017-05-19 10:18:13

    这个问题问得确实是有点…… 咋一看以为代码故意sleep了10秒然而题主看不懂,通过上面评论区的撕逼大概知道是在问什么了……

    这东东跟浏览器UI线程有关,浏览器是单线程的(这个线程一般就叫浏览器UI线程)。

    《高性能JavaScript》第六章 快速响应的用户界面,有这么两段话:

    大多数浏览器有一个单独的处理进程,它由两个任务所共享: JavaScript 任务和用户界面更新任务。 每个时刻只有其中的一个操作得以执行, 也就是说当 JavaScript代码运行时用户界面不能对输入产生反应,反之亦然。或者说,当 JavaScript 运行时,用户界面就被“锁定”了。管理好 JavaScript 运行时间对网页应用的性能很重要。

    JavaScript和UI更新共享的进程通常称做”浏览器UI线程”。UI线程的工作基于一个简单的队列系统,任务会保存到队列中直到进程空闲。一旦空闲,队列中下一个任务就被重新被提取出来并运行。这些任务要么是运行JS代码,要么执行UI更新,包括重绘和重排。

    function(){
        button.remove();
        func();    
    }

    这是点击事件的处理函数,js移除DOM节点后,func()马上接着运行,10秒后进程空闲,才会运行下一个任务,更新用户界面,这时候按钮才会在页面中消失。

    上面另一个答案评论区的问题,‘为什么添加的时候就不会有这种现象’

    添加的函数是这样的,

        createBtn: function (func) {
            var    button = $('<button>测试</button>'); //生成button
            button.bind("click",function(){   //给button绑点击事件
                button.remove();
                func();    
            });    
            $('body').prepend(button); //把button加到body上
        },

    这个过程并没有运行func(),试试把这个函数移出来,改成这样

        createBtn: function (func) {
            var    button = $('<button>测试</button>');
            button.bind("click",function(){
                button.remove();    
            });    
            $('body').prepend(button);
            func();
        },

    肯定也阻塞

    Antwort
    0
  • 为情所困

    为情所困2017-05-19 10:18:13

    应该是你阻塞了线程 使得图形渲染也'卡'住了

    即便button已从dom树中删除。

    但是图形没有把新的、不存在button的dom树重新绘制。

    Antwort
    0
  • 淡淡烟草味

    淡淡烟草味2017-05-19 10:18:13

    之前是我想的简单了,应该是和楼下说的一样,画面渲染卡住了。
    比如在func();之前打印一下日志:

    console.log(func);

    出现输出标识之后就卡住了,等到sleep执行完才把完整内容显示出来:

    sleep执行时页面被阻塞完全不能操作了,同时CPU占用非常高(因为这个循环理论上没有间隔,)可能是这个导致被卡住了吧。

    Antwort
    0
  • StornierenAntwort