Rhino Interpreter 中的 JavaScript - 函数返回未定义

Posted

技术标签:

【中文标题】Rhino Interpreter 中的 JavaScript - 函数返回未定义【英文标题】:JavaScript in Rhino Interpreter - function returns undefined 【发布时间】:2017-01-11 11:12:22 【问题描述】:

我正在使用 Blue 中的嵌入式 Rhino Interpreter(Csound 的音乐创作环境)来生成“乐谱”(乐谱)。在蓝色中,您可以通过编写函数然后执行来做到这一点

score = myFunction()

我的函数使用 onLoad 获取图像并提取像素信息,这些信息将用于生成分数。问题是我的函数没有足够的时间加载图像并在将数据分配给变量之前返回数据。我试过使用 setTimeout() 但这没有帮助。

我在浏览器中尝试过,它确实返回“未定义”。

基本上我需要一种延迟分配给分数变量的方法。这可能吗?

谢谢

function score()
    var img = new Image();
    img.src = "http://static.webshopapp.com/shops/023001/files/024718445/256x256x2/major-dog-barbell-mini.jpg";
    img.crossOrigin = "Anonymous";
    var score = "abc";
    img.onload = function()
        var canvas = document.createElement("canvas");
        canvas.width = img.width;
        canvas.height = img.height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);   
        var imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
        score = "i1 0 2 440 0.5\n"
        for (var i=0;i<imgData.data.length;i+=4)
            score += "i1 + 0.1 " + (imgData.data[i] + 500).toString() + " 0.5\n"
        
        return score;
    

score = score();
// TRY THIS IN BROWSER - RETURNS UNDEFINED
//console.log(score())

【问题讨论】:

【参考方案1】:

(这里是蓝的作者)

对于 Blue,它现在实际上使用的是 Java 8 中内置的 Nashorn。(我在新的 Blue 版本中将该对象重命名为 javascriptObject。)

Nashorn 提供了一个 JS 引擎,但据我所知,它并没有提供人们期望在浏览器中使用的所有 API。我运行并调试了您的代码,发现一些关于“文档”和“图像”未定义的异常被抛出。我使用Java对象重写了代码,例如:

function genScore()

    var url = new java.net.URL("http://static.webshopapp.com/shops/023001/files/024718445/256x256x2/major-dog-barbell-mini.jpg");
    var img = javax.imageio.ImageIO.read(url);


    score = "i1 0 2 440 0.5\n"
    for (var i = 0; i < img.getHeight(); i++) 
        for (var j = 0; j < img.getWidth(); j++) 
            var rgb = img.getRGB(i, j);
            score += "i1 + 0.1 " + (rgb + 500).toString() + " 0.5\n"
        ;
    
    return score;

score = genScore();

这大致奏效了。 (如果我理解正确,我认为您的代码仅使用红色值;必须使用位掩码修改此代码并移位以仅从 RGB 中获取 R 值;有关 Java 的 BufferedImage 类的更多信息,请访问https://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html )。

【讨论】:

此外,蓝色代码看起来只是将异常数据打印到应用程序日志,这使得调试变得困难。我已经为 2.7.0 修改了 Blue,以便它将这样的代码问题报告给用户。【参考方案2】:

你需要的是一个传入 score 函数的回调函数,当图片加载完成时会被触发:

// Adding a callback function as parameter
function score(callback)
    var img = new Image();
    img.src = "http://static.webshopapp.com/shops/023001/files/024718445/256x256x2/major-dog-barbell-mini.jpg";
    img.crossOrigin = "Anonymous";
    var score = "abc";

    img.onload = function()

        var canvas = document.createElement("canvas");

        canvas.width = img.width;
        canvas.height = img.height;

        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);   
        var imgData=ctx.getImageData(0,0,canvas.width,canvas.height);

        score = "i1 0 2 440 0.5\n"
        for (var i=0;i<imgData.data.length;i+=4)
        
            score += "i1 + 0.1 " + (imgData.data[i] + 500).toString() + " 0.5\n"
        
        // Now we can run the callback with our score data
        return callback(score);

    


score(function(score)

  console.log(score);
  // Do your stuff with score data...

);

【讨论】:

感谢您的回复,这在浏览器中就像一个魅力,但它在 Blue 中不起作用,它需要在主程序中使用 score = myFunction() 形式的东西(作业需要在任何功能之外发生)。你觉得我有什么办法可以做到吗? 异步调用的本质,要求你使用回调函数来取回结果。不幸的是,我不熟悉 Rhino 和 Blue 平台,以便在这方面提供更多帮助。您必须将 score=myFunction() 放在匿名函数中(console.log(score) 现在位于上面的代码中)或考虑使用 Promises(如果可用)。

以上是关于Rhino Interpreter 中的 JavaScript - 函数返回未定义的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Rhino 将 Java 类中的方法添加为 Javascript 中的全局函数?

Rhino 中的 XMLHttpRequest?

Rhino中的directoryList

使用 require.js 和 Java/Rhino 解析模块

使用 Rhino(Mozilla 的 rhino)的优点

Rhino:如何从 Java 调用 JS 函数