2016-12-11 78 views
0

我希望能夠捕獲延續並多次恢復,這樣每個這樣的調用將獨立於其他調用。是否有可能多次恢復犀牛的延續?

例如,在下面的代碼,我想在run方法2調用context.resumeContinuation以導致輸出:1 1,而不是1 2的電流輸出。

據我所知,結果輸出的原因是我總是使用相同的scope對象,在傳遞給第二個對象之前,第一個連續對象將被修改。因此,我似乎應該恢復原始scope複製,但Scriptable沒有clone方法(或任何等同的方法),並且使用序列化/反序列化對其進行復制也無濟於事。

P.S.我正在使用犀牛版本1.7R5。

Example.java

import org.mozilla.javascript.*; 
import java.io.IOException; 
import java.nio.file.Files; 
import java.nio.file.Paths; 

public class Example { 
    public void run() throws IOException { 
     Context context = Context.enter(); 
     context.setOptimizationLevel(-2); // Use interpreter mode. 
     Scriptable scope = context.initStandardObjects(); 
     scope.put("javaProxy", scope, Context.javaToJS(this, scope)); 

     Object capturedContinuation = null; 
     try { 
      String scriptSource = 
       new String(Files.readAllBytes(Paths.get("example.js"))); 

      String scriptName = "example"; 
      int startLine = 1; 
      Object securityDomain = null; 
      Script script = 
       context.compileString(scriptSource, scriptName, startLine, securityDomain); 
      context.executeScriptWithContinuations(script, scope); 
     } catch (ContinuationPending continuationPending) { 
      capturedContinuation = continuationPending.getContinuation(); 
     } 

     Object result = ""; 

     context.resumeContinuation(capturedContinuation, scope, result); 
     context.resumeContinuation(capturedContinuation, scope, result); 

     Context.exit(); 
    } 

    public void captureContinuation() { 
     Context context = Context.enter(); 
     ContinuationPending continuationPending = 
      context.captureContinuation(); 
     Context.exit(); 
     throw continuationPending; 
    } 

    public void print(int i) { 
     System.out.print(i + " "); 
    } 

    public static void main(String[] args) throws IOException { 
     new Example().run(); 
    } 
} 

example.js

var i = 1; 
javaProxy.captureContinuation(); 
javaProxy.print(i); 
i = i + 1; 

回答

0

於是我想出了一個有效的解決方案:

而是複製scope的對象,我應該複製capturedContinuation對象,所以2調用resumeContinuation是:

context.resumeContinuation(deepCopy(capturedContinuation), scope, result); 
context.resumeContinuation(deepCopy(capturedContinuation), scope, result); 

This question提供deepCopy方法可能imeplementations。

雖然:Rhino的NativeContinuation類型(這是上面代碼中的動態類型capturedContinuation)的實例似乎非常大(當序列化爲字節數組時,大小約爲15KB),因此時間/在應用程序中深度複製它們時應考慮內存消耗影響。