用 js 遍历数组,然后调用 python 脚本处理数组元素,但得到的结果却是乱序的
发布于 7 年前 作者 mind1949 2731 次浏览 来自 问答

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?

类似这种的

@hyj1991

  1. 第二个问题的原因听懂了.谢谢哈😆;
  2. 第一个问题我的理解是这样,前辈帮忙看看哈:
  • 因为 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 嗯嗯. 谢谢前辈指点🙏

回到顶部