用 js 遍历数组,然后调用 python 脚本处理数组元素,但得到的结果却是乱序的
1. 代码:
1.1 js脚本
// call_py.js
// 制作数组
var s1="1 What makes Rails so great?"
var s2 = "2 do you love me still ?"
var s3 = "3 The Ruby on Rails Tutorial is designed to give you a thorough introduction to web application developmentntrepreneur."
var s4 = "4 of course i still love you . "
var list=[s1,s2,s3,s4]
// 子进程
var exec = require('child_process').exec;
// 遍历数组
let iterable = list
for(let value of iterable)
{
exec('python py_test.py '+value+' ',function(error,stdout,stderr)
{
if(error){
console.log(stderr)
}else{
console.log(stdout)
}
}
)
}
1.2 python脚本:
# py_test.py
import sys
script = sys.argv
print script
1.3 输出的结果:
['py_test.py', '1', 'What', 'makes', 'Rails', 'so', 'great?']
['py_test.py', '2', 'do', 'you', 'love', 'me', 'still', '?']
['py_test.py', '3', 'The', 'Ruby', 'on', 'Rails', 'Tutorial', 'is', 'designed', 'to', 'give', 'you', 'a', 'thorough', 'introduction', 'to', 'web', 'application', 'developmentntrepreneur.']
['py_test.py', '4', 'of', 'course', 'i', 'still', 'love', 'you', '.']
2.疑问:
2.1 问题一:
- 为什么输出的结果不是按照数组的顺序来的,而是乱序的?
- 怎样才能输出按照数组顺序的结果?
2.2 问题二:
- 因为我在js脚本的第18行用的是
'python py_test.py '+value+' '
,所以我觉得应该是将value
作为一个值传递给python脚本,但是实际输出结果却显示是拆分成了很多个词,然后变成了很多个值?
5 回复
对于第二个问题,解法是将python py_test.py '+value+'
改成:
python py_test.py "'+value+'"
顺序不是 1 2 3 4 么,就是按照顺序的,不过 child_process.exec 是异步调用,顺序本来就是不固定的 你传给 python 脚本的字符串带了空格,不就是和命令行输入时空格的效果一样么,一个空格代表一个参数啊,当然会隔开了
python py_test.py 1 What makes Rails so great?
类似这种的
- 第二个问题的原因听懂了.谢谢哈😆;
- 第一个问题我的理解是这样,前辈帮忙看看哈:
- 因为 js 调用其他脚本的模块只有 child_process ,只有这个模块能够实现调用其他脚本,所以使用 js 无法保证返回结果的顺序.
- 虽然无法保证返回结果顺序,但是可以将返回结果做成数组,然后排序,最终得到自己想要的顺序.
@mind1949 你这样想逻辑上也走得通,但是最后的排序多此一举了,可以把异步的 exec 封装成 promise,再用 Promise.all 调用即可保正返回的结果顺序:
function exec(value) {
return new Promise((resolve, reject) => {
require('child_process').exec(`python py_test.py "${value}"`, function (error, stdout, stderr) {
error ? reject(error) : resolve(stdout);
});
});
}
var s1 = "1 What makes Rails so great?"
var s2 = "2 do you love me still ?"
var s3 = "3 The Ruby on Rails Tutorial is designed to give you a thorough introduction to web application developmentntrepreneur."
var s4 = "4 of course i still love you . "
var list = [s1, s2, s3, s4];
Promise.all(list.map(argv => exec(argv))).then(datas => console.log(datas));
@hyj1991 嗯嗯. 谢谢前辈指点🙏