12

私はテストをしています:

HTML:

<div id="f1">Empty</div>
<div id="f2">Empty</div>

​

js:

var s1 = function() {
    for (i = 1; i < 1000000000; i++) {
        var b = i * i;
    }
    $('#f1').html('Set');
}

var s2 = function() {
    if ($('#f1').html() == 'Empty') {
        $('#f2').html('Multi Thread');
        return;            
    };
    $('#f2').html('One Thread');
}

setTimeout(s2,110);
setTimeout(s1,100);​

setTimeOut()がイベントモデルのように別のスレッドで実行されない本当の理由はありますか?

jsfiddle

4

8 に答える 8

17

Javascript自体は、マルチスレッドでも非マルチスレッドでもありません。ただし、現在主要なブラウザに実装されているJavascriptの特定の実装は、ほとんどがシングルスレッドです。

さらに、適切なマルチスレッド化のために、言語には、共有メモリ、ロック、セマフォ、およびその他の並行プログラミングツールの機能が必要です。これは、現在定義されているJavaScriptにはありません(たとえば、並行JSスレッドがどのようになるかを説明する方法はありません)。もちろん、ウィンドウにはDOMが1つしかないため、共有されるDOMオブジェクトを誰が更新できるかを制御します。

JSをより並列化する試みがあります。Webワーカー、IntelのRiver Trail、GoogleのHTML5の動作などを見てください

于 2012-08-29T22:36:18.287 に答える
4

eicto、要求されたときにsetTimeoutコードを起動しません。 コードをインラインでキューに入れ、その前にある他のすべてのコードと一緒にキューに入れますが、少なくとも要求された時間になるようにコードを並べます。

さらに、ほとんどのブラウザには、最小タイムアウトの厳しい制限があります。
1ミリ秒のタイムアウトをリクエストした場合、ほとんどのブラウザでは、リクエストが10ミリ秒から15ミリ秒後に返される可能性があります。

すべてのJSとDOMの相互作用、そして実際には、単一のページが行うほとんどすべてのことは、カスタムブラウザ拡張機能といくつかの新しいAPI(Webworkerなど)の特定の例外を除いて、すべて1つのスレッドで行われます。

これが、大規模なプロジェクトがページ上の他のすべてを考慮する必要がある理由であり、すべてが非同期である必要がある理由です。

setTimeoutはではなく、編集さsleepれた正確なマイクロ秒に戻らないためcronです... ...指定した時間よりも早く、イベントスタックにコールバックを置きます。

于 2012-09-27T20:59:21.450 に答える
4

ブラウザーのDOMおよび他のグローバル変数/プロパティへのシングルスレッドアクセスのみを想定したブラウザーでのJavascriptの実装には、多くの設計上の決定が行われました。これにより、プログラミングで問題が発生する可能性は大幅に低くなりますが、対処しなければならないいくつかの制限が生じます。

言語自体は完全にマルチスレッド化することができ、WebWorkersおよび言語の一部のサーバー実装ですでにそれを確認しています。ただし、複数のスレッドを使用して、複数のスレッド間で共有される変数またはプロパティの読み取り/書き込みを試みる場合は常に、それらの共有リソースへの信頼できるアクセスを可能にするために保護デバイス(ミューテックスなど)を使用する必要があります。これは、このプログラミングを行う方法を大幅に複雑にし、ブラウザでJavascriptを実行するために、そのレベルの理解を必要としないことを決定しました。

マルチスレッドプログラミングを行ったことがある人にとっては強力ですが、見つけるのが難しいバグを導入するのは非常に簡単です。ブラウザのJavascriptの責任者は、そのレベルの難しさと結果として生じるタイプのバグを完全に回避する必要があると判断しました。

現在でもWebWorkersを使用しているため、WebWorkerとメインのjavascriptスレッドの間に共有リソースはありません。2人は、安全を強制するための絶対確実な方法であるメッセージパッシングシステムを介して通信する必要があります。その結果、WebWorkerからDOMにアクセスできなくなります。代わりに、DOMを変更する場合は、単一のメインスレッドにメッセージを投稿し、ITにDOMを更新するように依頼する必要があります。メインスレッドは、他のことを行ったときにのみそのメッセージを受け取ります(シングルスレッドです)。

また、DOMはシングルスレッドアクセス専用に設計された構造として数十億年を費やしている可能性が高いため、複数のスレッドからDOMにアクセスする方法を設計および実装する(そして結果として生じるすべてのバグを修正する)ことは巨大な作業になります。その実装では)。

于 2012-08-29T22:52:12.287 に答える
2

ブラウザのインタプリタはシングルスレッドであるため、Javascriptはマルチスレッドをサポートしていません

于 2012-08-29T22:33:13.503 に答える
1

JavaScriptはマルチスレッドではありませんが、setTimeoutであったとしても同期です。setTimeoutとsetIntervalは、適切なJavaScript言語の外部のブラウザーによって提供されます。これにより、イベントの実行など、言語にアクセスするための外部手段が提供されます。JavaScriptを非同期言語またはマルチスレッド言語と呼ぶ場合、これはおそらく彼らが指しているものです。これは、多数のタイマーやイベント実行などの複数の外部アクセスポイントが同時に発生し、それぞれがメモリ内のインタープリターに一意のアクセスポイントを生成するためです。これは、Node.jsの開発者がJavaScriptについてそのような主張をするときに言及しているものです。

シミュレートされたマルチスレッド効果により、ページ全体を表す単一のドキュメントオブジェクトしかないブラウザ出力で衝突が発生する可能性があるため、さまざまな分離スレッドへの複数の外部アクセスにより、UIで衝突が発生する可能性があります。これが、間隔が短いsetIntervalが一般的に安全でないと見なされる理由です。setIntervalは完全に非同期であり、前の間隔での実行が終了していなくても、指定された間隔に従って実行されます。この種の衝突は、私がフォールオーバーと呼んでいるものです。次の間隔は、前の実行にフォールオーバーするコードを実行しているためです。コードがDOMへのアクセスを必要とする場合、またはクロージャを使用する場合は、問題が発生する可能性があります。安全のために、再帰的なsetTimeoutをお勧めします。

于 2012-08-29T23:00:49.567 に答える
0

Javascriptはマルチスレッドではありません。

HTML5はjavascriptマルチスレッド機能を提供します。

于 2012-08-29T22:33:17.953 に答える
0

Mozillaは、複数のスレッドからUI作業を行いたくない限り、Javascriptでマルチスレッドをサポートします。重複メッセージの削除(代替)拡張の初期バージョンはマルチスレッドでした。

私の拡張機能のこの問題に関する私自身のバグページを参照してください。さらに良いことに、Mozillaでのワーカースレッドの使用に関するこのページを参照してください。eicto、バックグラウンドスレッドを使用してコードを非常にうまく実装できます。

于 2012-09-27T20:44:55.600 に答える
-1

指定された時間待機した後も、メソッド(s1、s2)の実行は、javascriptスレッド自体(シングルスレッド)で行われます。

s2がs1を待機する理由。

于 2020-01-28T13:17:51.377 に答える