tur*_*_34 3 javascript php node.js es6-promise
我有一个 PHP 脚本,它使用该exec函数来执行 Node 脚本并将一些数据返回到同一 PHP 脚本。
我的问题是我需要将数据返回给 PHP,而不必等待清理代码完成finally。
我在下面编写了一些示例代码,向您展示代码的流程并说明我的问题。该代码示例不使用任何节点模块,但如果它们有帮助,请随意使用它们。
示例.php
$data = 'hello world';
$exec = 'node example.js ' . $data;
$escaped_command = escapeshellcmd($exec);
$data = exec($escaped_command);
// waits 10 seconds then displays returned data
// I need the code to return before finally executes
var_dump($data); // string(31) "Final data is final hello world"
Run Code Online (Sandbox Code Playgroud)
示例.js
let data = process.argv[2];
// let data = "hello world";
async function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
const doSomething = data => new Promise((resolve, reject) => {
if (data) {
resolve("new hello world");
} else {
reject();
}
});
const doSomethingElse = newData => new Promise((resolve, reject) => {
if (newData) {
resolve("final hello world");
} else {
reject();
}
});
(async() => {
try {
let newData = await doSomething(data);
let finalData = await doSomethingElse(newData);
// return this to server/php right now.
// Do not wait until finally script finishes
console.log("Final data is " + finalData);
} catch (err) {
// if error return this to server/php right now.
// Do not wait until finally script finishes
console.log(err);
} finally {
// does cleanup/closes node app
await timeout(10000);
}
})();
Run Code Online (Sandbox Code Playgroud)
使用proc_open异步运行进程。让节点尽快输出数据。无需等待节点完成即可读取此数据:
// foo.js
process.stdout.write(JSON.stringify({"foo":"bar"})+"\n");
// simulate cleanup
setTimeout(() => {}, 3000);
// foo.php
<?php
$io = [
0 => ['pipe', 'r'], // node's stdin
1 => ['pipe', 'w'], // node's stdout
2 => ['pipe', 'w'], // node's stderr
];
$proc = proc_open('node foo.js', $io, $pipes);
$nodeStdout = $pipes[1]; // our end of node's stdout
echo date('H:i:s '), fgets($nodeStdout);
proc_close($proc);
echo date('H:i:s '), "done\n";
Run Code Online (Sandbox Code Playgroud)
示例输出:
$ php foo.php
14:59:03 {"foo":"bar"}
14:59:06 done
Run Code Online (Sandbox Code Playgroud)
proc_close 将等待节点进程退出,但您可以推迟等待,直到完成 PHP 中的其他操作。
如果您不调用 proc_close,则可能会出现僵尸进程,具体取决于您的环境。Docker 和 PID 1 僵尸收割问题包含了很好的解释。很多时候都是指docker,因为这里是僵尸经常出现的地方,但是还是普遍适用的。
某些服务器 API 具有为客户端“隐形”运行代码的规定。例如,fcgi 有fastcgi_finish_request,您可以在 proc_close 之前调用它。这样 HTTP 客户端就不会注意到等待时间。
如果您不能容忍最终等待节点,请考虑将节点事物改为 Web 服务,它独立于 PHP 进行管理。
| 归档时间: |
|
| 查看次数: |
6066 次 |
| 最近记录: |