使用J2V8中的promise

时间:2016-07-26 15:18:00

标签: javascript java java-native-interface j2v8

我试图通过J2V8在Java项目中使用inline-css NPM包,将样式表内联到样式属性中。

final NodeJS nodeJS = NodeJS.createNodeJS();
final V8Object inlineCss = nodeJS.require(new File(
    "path/to/node_modules/inline-css/index.js"
));
final V8 jsRuntime = nodeJS.getRuntime();

final Map<String, Object> inlineOptions = new HashMap<>();
inlineOptions.put("applyLinkTags", false);
inlineOptions.put("removeStyleTags", false);
inlineOptions.put("url", "http://example.com");

jsRuntime.add("inlineCss", inlineCss);
jsRuntime.add("inlineOptions", V8ObjectUtils.toV8Object(jsRuntime, inlineOptions));

try (FileInputStream inputStream = new FileInputStream(pageFile)) {
    byte[] data = new byte[(int) pageFile.length()];
    inputStream.read(data);

    String pageContent = new String(data, "UTF-8");

    JavaVoidCallback successCallback = new JavaVoidCallback() {
        @Override
        public void invoke(V8Object v8Object, V8Array v8Array) {
            //...
        }
    };

    JavaVoidCallback errorCallback = new JavaVoidCallback() {
        @Override
        public void invoke(V8Object v8Object, V8Array v8Array) {
            //...
        }
    };

    jsRuntime.add("pageContent", pageContent);
    jsRuntime.registerJavaMethod(successCallback, "onSuccess");
    jsRuntime.registerJavaMethod(errorCallback, "onError");

    jsRuntime.executeObjectScript("inlineCss(pageContent, inlineOptions).then(onSuccess).catch(onError)");
} catch (IOException | V8ScriptExecutionException | V8ScriptCompilationException e) {
    //...
}

但是既不会调用成功也不会调用错误回调,也不会抛出任何错误。我找不到任何适用于J2V8的文档,所提供的示例在这里并没有什么帮助。有没有人用过J2V8来处理JavaScript的承诺?或者有人看到错误?

另外,如果你知道一个好的Java库来内联CSS也会有所帮助。到目前为止我遇到的那些在你有多个类和元素的id时并不能真正可靠地工作。 CSSBox看起来像是一个很有前途的解决方案,但它似乎没有正确处理供应商前缀规则。

另一种选择是使用CLI脚本,但这是我的最后选择,因为这意味着我还需要在我的Java应用程序旁边部署NodeJS。

1 个答案:

答案 0 :(得分:2)

您必须抽取Node.js消息循环:

while(nodeJS.isRunning()) {
  nodeJS.handleMessage();
}

将此添加到代码的底部,它应该可以工作。另外,我注意到你有onSuccess(c),我认为 c 应该是 pageContent