1

jQueryターミナルを使用して、次のようなコードがあります。

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

このコードペン内 では、ブラウザウィンドウを水平方向にサイズ変更するまで、行は表示されません。setTimeout 0 にフラッシュを入れると機能します。

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

ローカル サーバーで同じコードを (setTimeout なしで) 実行すると、正常に動作します。また、コードをiframeに埋め込もうとしましたが、期待どおりに実行されました。また、コマンド show (show と入力して Enter キーを押す) を実行すると、実行されたコマンドとプロンプトが最後 (echo によって追加された行の後) に追加されますが、ウィンドウのサイズを変更すると、必要に応じて行の前に配置されます。

なぜこれが起こっているのか、誰にも手がかりがありますか?コードがローカルと codepen で異なる方法で実行されるのはなぜですか?

jquery.terminal-src.js ファイルにブレークポイントを設定しようとしましたが、フラッシュしても行が表示されない理由がわかりませんでした。コードをステップ実行すると、フラッシュが呼び出されたときに output_buffer 配列が空のように見えますが、ウィンドウのサイズを変更してサイズ変更メソッドを実行すると、どういうわけか行が表示されます。

4

1 に答える 1

2

これは、echo関数が非同期であるためだと思います。Deferred内部で使用され、次のように文書化されています

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

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

次に、「即時」に実行されるが非同期に実行されるresolveの JQueryDeferredの が、 の呼び出し後に起動されることがあります。したがって、フラッシュはその時点では何もフラッシュしません。echoflush

の後に発生setTimeoutするようにキューを設定します。flushecho

私の意見では、echo (または任意のメソッド) に deferred を使用する場合は、すべてのメソッドを調整する必要があります。したがって、フラッシュも deferred を使用する必要があります。これはキューに入れられ、順番に解決されます。

ウィンドウのサイズを変更すると、後でフラッシュが強制されるだけです。これが表示される理由です。

ちなみに、オブジェクトの作成も延期されているようです。したがって、(setTimeout ではなく) メソッドで変数を使用すると、変数がまだ初期化されておらず、エラーが発生することがわかりますtermshowこれは、変数の割り当ての前に show 関数が呼び出されることを意味します。これは、非同期の混乱のもう 1 つの原因です。

于 2016-12-14T21:53:06.420 に答える