简体   繁体   English

我的代码在本地和Codepen或plunker中执行的方式不同

[英]My code is not executed the same locally and in codepen or plunker

I have code like this using jQuery Terminal: 我有使用jQuery Terminal这样的代码:

function show() {
    for (var i = 0; i < 100; ++i) {
        this.echo('line ' + i, {
            flush: false
        });
    }
    this.flush();
    setTimeout(function() {
        //this.flush();
    }, 0);
}

var term = $('body').terminal({
    show: show
}, {
    onBlur: function() {
        return false;
    },
    onInit: function(term) {
        show.apply(term);
    }
});

and inside this codepen the the lines are not show up until I resize horizontally the browser window. 在此Codepen中 ,直到我水平调整浏览器窗口的大小时,线条才会显示出来。 It work when I put flush in setTimeout 0: 当我在setTimeout 0中放入flush时,它起作用:

setTimeout(function() {
    term.flush();
}, 0);

It work normally when I run the same code (without setTimeout) in local server. 当我在本地服务器中运行相同的代码(没有setTimeout)时,它可以正常工作。 I've also tried to embed the code in iframe and It also run as expected. 我还尝试将代码嵌入到iframe中,并且也可以按预期运行。 And other thing when I execute command show (type show and press enter) the executed command and prompt is add at the end (after the lines added by echo) but when I resize the window they are in placed before the lines as they should. 另外,当我执行命令显示(键入显示并按Enter)时,已执行的命令和提示会添加到末尾(在echo添加的行之后),但是当我调整窗口大小时,它们会按需放置在行之前。

Anybody have a clue why this is happening? 有人知道为什么会这样吗? Why is the code executed differently locally and in codepen? 为什么在本地和在Codepen中执行的代码不同?

I've trid to setup breakpoints in jquery.terminal-src.js file but didn't figure out why flush don't make lines show up. 我试图在jquery.terminal-src.js文件中设置断点,但没有弄清楚为什么flush不会显示行。 When I step throught the code it seems that output_buffer array is empty when flush is called but somehow the lines show up when I resize the window and resize method is executed. 当我逐步执行代码时,似乎在调用flush时output_buffer数组为空,但是当我调整窗口大小并执行resize方法时,代码以某种方式显示。

I believe this is because the echo function is asynchronous. 我相信这是因为echo函数是异步的。 It uses Deferred internally and is documented as 它在内部使用Deferred ,并记录为

// :: it use $.when so you can echo a promise
// -------------------------------------------------------------
echo: function(string, options) {

In race conditions due to the Codepen overhead (generated code executed by codepen : note the window.CP lines added automatically) 在竞态条件下,由于Codepen的开销(由Codepen执行的生成代码:请注意window.CP行会自动添加)

for (var i = 0; i < 100; ++i) {
    if (window.CP.shouldStopExecution(1)) {
        break;
    }
    this.echo('line ' + i, { flush: false });
}
this.flush();
setTimeout(function () {
}, 0);
window.CP.exitedLoop(1);

Then it happens that the resolve of the JQuery Deferred of the echo which is performed "immediately" but yet asynchronously is fired after calling the flush . 然后发生的情况是, 调用flush 之后, “立即”执行但对异步执行的echo的JQuery Deferred resolve被触发。 Thus the flush flushes nothing at that time. 因此,当时冲洗不会冲洗任何东西。

Setting a setTimeout queues the flush such that it happens after the echo . 设置setTimeoutflush setTimeout队列,使其 echo 之后发生。

In my opinion, if they use deferred for the echo (or any method), they should align all the methods to do so. 我认为,如果他们将deferd用于回显(或任何方法),则应对齐所有方法。 And therefore the flush should also use deferred which would then be queued and would resolve in order. 因此,刷新还应使用deferred,然后将其排队并按顺序解决。

Resizing the window is just forcing a flush afterwards, this is why it displays then. 调整窗口大小只是在之后强制刷新,因此才显示窗口。

By the way, the object creation also seems to be deferred. 顺便说一下,对象的创建似乎也被推迟了。 Thus, if you use the variable term in the show method (not in the setTimeout) you will notice that it is not yet initialized and causes an error. 因此,如果在show方法中使用变量term (而不是在setTimeout中),则会注意到该变量term尚未初始化,并会导致错误。 This means that the show function is called before the variable assignment. 这意味着show函数在变量赋值之前被调用。 Which is another cause for asynchronous confusion. 这是造成异步混乱的另一个原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM