2011-12-23 9 views
15

私はJDKのjavax.script。*パッケージを使用しています。具体的には、JavaScriptエンジンを使用しています.JavaScriptエンジンは、私が読んだところでは、Mozillaが開発したRhinoというJavaScript-in-Javaインタープリタに基づいているようです。RhinoでJavaでJavaScriptを解釈する:スクリプトの一時停止/再開

私が達成しようとしているのは、基本的には、自分のJavaScriptをコード内の特定のポイント(たとえば、関数呼び出しの途中)で「一時停止」でき、後でJavaが許可したときに再開できるそう。

function myJSFunction() { 
    print("Hello "); 
    mysteriousPauseFunction(); // this is the part I'm wondering about. basically, the script should break here and resume later at Java's discretion... 
    // upon reaching this comment, we know now that Java has told JavaScript that it's okay to resume, so the next line will now be executed... 
    print("world"); 
} 

「一時停止」/「破壊」の部分は、Javaの機能を結合し、それを現在のたScriptEngineへの参照または何を渡す関係している場合、それはだ:、私が何を意味するかを示し、このJavaScriptコードを想像する

私と一緒に涼しい。私はそれがおそらく、Java内からJavaScriptを一時停止することであると考えています。

私はいくつかの検索を行い、ここのキーワードが「継続」であることがわかりました。私が知る限り、Rhinoはインタプリタモード(コンパイルモードと比較して)でのみ継続をサポートしていますが、これは "コンテキスト"を-2に設定することで実現します。組み込みのJDK ScriptEngineはコンテキストについて何も言及していないので(あるいは、私が紛失しているかもしれない)、これはMozillaのRhinoライブラリを直接ダウンロードして使用する必要があるのでしょうか?

これを達成するために必要なのはRhinoの継続ですか?私はa useful tutorialをRhinoの続きで見つけましたが、それを読んだ後、私が上で説明したことを達成できるかどうかは100%確信していません。このの場合、私のフォローアップの質問は「シリアライゼーション」です。私のスクリプトを再開すると、シリアル化しない限り、すべての変数は設定されていませんか?

更新:これはRhinoで可能です。これまでのところ私のJavaScriptには何がありますか?コードの後に​​、私は...それが何をするかを説明します

var end = new Continuation(); 

function myJSFunction() 
{ 
    print("Hello "); 
    var kont = new Continuation(); 
    storePause(script, kont); // script is previously bound by Java into the JavaScript. it is a reference to the script itself. 
    end(); 
    print("world"); 

} 

マイ「storePause()」関数は、それを今、私が書いたJava関数であり、それはJavaScriptにバインドされていますが、何もしない。私の次の目標は、Javaがスクリプトを後で再開できるように、Javaオブジェクトとして継続情報とスクリプト情報を格納するようにコードを完成させることです。

「Hello」が印刷されてから「world」が印刷される前に、スクリプトを一時停止または「中断」しているので、この方法でスクリプトを一時停止することができます。

この時点で私が把握しておくべきことは、継続を再開する方法です。上記の動作は、デフォルトでJDKスクリプトエンジンを使用していることに注意してください(私はこの時点でインタプリタモードとコンパイルモードを心配する必要はなく、デフォルトの解釈モードと思われます)が、スクリプトを再開するプロセスのようですMozillaのRhinoライブラリが必要です。

答えて

5

申し訳ありませんが、私はドキュメント、チュートリアル、および例を掘り下げてここにもRhino Google Groupに投稿しましたが、実際のソリューションをコンパイルできました。完全な例はないように思われるので、私はここでこれを見越して誰かのためにここに結果を投稿します。

実は、私の調査結果は、おそらくここに投稿するには長すぎるので、私は私のブログにチュートリアルを書くことにした:誰かを助け

http://www.joshforde.com/blog/?p=7

ホープ。私が知る限り、これはRhinoの初期化、JavaScript(* .js)ファイルからのスクリプトの読み込み、特定のJavaクラスのすべての関数の自動バインド(ScriptFunctionsなど)をJavaScriptでグローバル関数として使用し、最後にJavaScript関数を呼び出してその呼び出しの継続を処理します。

基本的に(JDKでパックのバージョンが古くなっていると継続をサポートしていないため)、問題は私が最初のMozilla Rhinoのソースコードをダウンロードするために必要なことだった、公式を使用するように私のコードのすべてを書き換えますRhinoパッケージの構文(JDKのScriptingEngine構文とはまったく異なります)、ContinuationPending例外をスローしてJavaScriptにバインドするためのJava関数を記述します.JavaScriptから直接ContinuationPendingをスローすると、JavaScriptExceptionがスローされ、 ContinuationPendingがスローされ、そのJavaScriptExceptionでgetCause()を呼び出そうとするとnullになります)、JavaScript関数(私の元の例では "myJSFunction")を呼び出すJavaコードで、try/catchブロックでContinuationPending(whi chは例外です)、その後、そのContinuationPending を使用してスクリプトを再開します。

Phew。それは厳しいものでしたが、今はそれだけの価値があります。

+0

ブログのサイトが応答していません。 –

+1

@JesseGlickがヘッドアップに感謝します。私のサイトを新しいWebサーバーなどに移動する必要があるように見えます。その間、archive.orgのバージョンは次のとおりです。https://web.archive.org/web/20130730231256/http://www.joshforde.com/blog/index.php/2011/12/tutorial-continuations-in -mozilla-rhino-a-javascript-interpreter-for-java / – Josh1billion

-1

あなたが通知/待って使用することができます

public final class Pause { 
    private final Object lock = new Object(); 

    public void await() throws InterruptedException { 
    synchronized (lock) { 
     lock.wait(); 
    } 
    } 

    public void resumeAll() { 
    synchronized (lock) { 
     lock.notifyAll(); 
    } 
    } 
} 

使用法:

final Pause pause = new Pause(); 

class Resumer implements Runnable { 
    @Override public void run() { 
    try { 
     Thread.sleep(5000); 
     pause.resumeAll(); 
    } catch (InterruptedException e) { 
     Thread.currentThread().interrupt(); 
    } 
    } 
} 
new Thread(new Resumer()).start(); 

SimpleBindings bindings = new SimpleBindings(); 
bindings.put("pause", pause); 
String script = "print('Hello, ');\n" 
       + "pause.await();\n" 
       + "println('ECMAScript!');\n"; 
new ScriptEngineManager().getEngineByName("ECMAScript") 
         .eval(script, bindings); 

これは、あなたが他の制約を言及していないような比較的単純なソリューションです。 wait()はスレッドをブロックしますが、これはすべての環境で受け入れられません。また、スクリプトを同時に実行する場合は、Pauseインスタンスで待機中のスレッドを識別する簡単な方法もありません。

注:await()InterruptedExceptionは、発信者が処理するか、await()でより賢明な処理を行う必要があります。

+0

ありがとうございます。私が利用しようとしているのは、Rhinoの実際の「継続」機能です。数日間の研究とデバッグの後、私はついにこれを達成する方法を見つけました。だから、将来この情報を探している人には答えを投稿します。 – Josh1billion

0

あなたはこれをやっていたが、私はこのように、エンドユーザーと対話するプログラムをエミュレートした理由を説明しませんでした:

print('Hello!'); 
a=Number(input('enter a number')); 
b=Number(input('and another number')); 
print('the sum of '+a+' plus '+b+' is '+(a+b)) 

私はそれがプリントを作成することにより、単に作業を持っているとプログラムの状態をチェックするjavascriptの入力関数。あなたが任意のブラウザでソースコードを見ることができるように

あなたはそれがすべてのJavaScriptで書かれてdemo here.

を見ることができます。

希望します。