javascript - 如何从函数中的子进程返回值?

标签 javascript python node.js botframework child-process

我在 javascript 中生成了一个 python 子进程(用于使用 Microsoft Botframework 编写 Bot),如下所示:

async function searchForRelevantDoc (context) {
    var msg = context.activity.text;
    var spawn = require('child_process').spawn,
        py    = spawn('python', ['../path/to/file.py', msg]),
        output = '';
    py.stdin.setEncoding = 'utf-8';
    py.stdout.on('data',
    (data) => {
        output += data.toString();
        console.log('output was generated: ' + output);
    });
    // Handle error output
    py.stderr.on('data', (data) => {
    // As said before, convert the Uint8Array to a readable string.
        console.log('error:' + data);
    });
    py.stdout.on('end', async function(code){
        console.log('output: ' + output);
        console.log(`Exit code is: ${code}`);
        // "return" is probably wrong, what should be done instead?
        return output;
        }
    });
}

我希望 output 作为函数 searchForRelevanceDoc() 的值返回。如何才能做到这一点?我无法使用 等待 context.sendActivity(输出) 而不是返回语句。错误信息:

TypeError: Cannot perform 'get' on a proxy that has been revoked

函数 searchForRelevanceDoc 的调用方式如下:

//in bot.js
const pysearch = require('../bboti/python-search');

class MyBot {

    // constructor...

    async onTurn(context) {
        // ...
        var search_engine_answer = pysearch.searchForRelevantDoc(context);
        context.sendActivity(search_engine_answer)
        // ...
    }
}

最佳答案

返回/解决的最简单方法output来自 searchForRelevantDoc , 使用 async/await就是用events.once这是在 Node 11.13.0 中添加的,并等待 close py的事件

const { once } = require('events'); // Added in Node 11.13.0

async function searchForRelevantDoc (context) {
    var msg = context.activity.text;
    var spawn = require('child_process').spawn,
        py    = spawn('python', ['../path/to/file.py', msg]),
        output = '';

    py.stdin.setEncoding = 'utf-8';

    py.stdout.on('data', (data) => {
        output += data.toString();
        console.log('output was generated: ' + output);
    });
    // Handle error output
    py.stderr.on('data', (data) => {
    // As said before, convert the Uint8Array to a readable string.
        console.log('error:' + data);
    });
    py.stdout.on('end', async function(code){
        console.log('output: ' + output);
        console.log(`Exit code is: ${code}`);
    });

    await once(py, 'close')

    return output;
}

如果您使用的是旧版本的 Node,您可以将其包装在 new Promise


async function searchForRelevantDoc (context) {
    // ...

    // You can also check for `code` and reject if a non zero code is returned
    await new Promise(resolve => py.on('close', resolve));

    return output;
}

然后在调用 searchForRelevantDoc 时你需要使用 await.then

class MyBot {

    // constructor...

    async onTurn(context) {
        // ...
        var search_engine_answer = await pysearch.searchForRelevantDoc(context);
        context.sendActivity(search_engine_answer)
        // ...
    }
}

关于javascript - 如何从函数中的子进程返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59107079/

相关文章:

c# - 将值传递给 ASP.NET 中的 javascript

javascript - Meteor - #数组的每次迭代,并在每个第 n 项后插入另一个 HTML 元素

python - PyEphem 中的 .parallctic_angle() 方法

python - 参数验证,Python 中的最佳实践

javascript - AngularJS如何拥有网站服务器SEO友好的页面

javascript - 不使用JSONP启用跨域请求

python - 关键错误 = client_id -- django

javascript - 使用 Yargs 执行代码之前要求用户确认

node.js - 当新的主 Node 当选后,Express 无法连接到 mongodb 副本集

javascript - Mongodb 到 Android 应用程序