原文链接: execa 进程库
上一篇: nodejs 函数缓存库 memoizeOne 和 micro-memoize Memoizee
下一篇: github 配置 travis 自动发布 release
github
https://github.com/sindresorhus/execa#readme
一个进程处理的封装库
fib.js
求前40项, 每次2s
function fib(n) {
return n < 2 ? n : fib(n - 1) + fib(n - 2)
}
let st = +new Date()
let list = []
for (let i = 0; i < 40; i++) {
list.push(fib(i))
}
let ed = +new Date()
console.log(
JSON.stringify(
{
list,
time: ed - st
}
)
)
// {"list":[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578,5702887,9227465,14930352,24157817,39088169,63245986],"time":2102}
多进程下对计算密集型可以加速
执行多次时, 总时间基本上是最长时间, 虽然单次任务执行时间变长了, 但总时间大大减少
const execa = require('execa');
// 单次执行
// stdout {"list":[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578,5702887,9227465,14930352,24157817,39088169,63245986],"time":2042}
(async () => {
let st = +new Date()
let list = [...Array(16)].map(
() => execa('node', ['fib.js'])
)
let times = (await Promise.allSettled(list)
).map(
// console.log
i => JSON.parse(i.value.stdout).time
)
let ed = +new Date()
console.log('stdout', ed - st, times);
// 16
// stdout 9254 [
// 5724, 5249, 5509, 6243,
// 7173, 8206, 7295, 6829,
// 6274, 6951, 7923, 7215,
// 6972, 7300, 6570, 6053
// ]
// 10
//stdout 5665 [
// 4902, 4897, 4929,
// 4991, 4928, 4973,
// 4991, 4925, 4855,
// 4894
// ]
// 8
// stdout 4550 [
// 4145, 4043, 3983,
// 4111, 4129, 4064,
// 3997, 3962
// ]
// 6
// stdout 3983 [ 3629, 3425, 3620, 3557, 3584, 3466 ]
// 4
// stdout 2916 [ 2608, 2619, 2686, 2576 ]
// 2
// stdout 2277 [ 2108, 2099 ]
// 1
// stdout 2145 [ 2021 ]
})();
父子进程通信
child 接受消息, 可以传递json, 返回处理结果
process.on('message', data => {
console.log('child receive', data)
process.send(
{
'msg': "child " + data.msg
}
)
})
parent, 发出消息, 输出返回结果和child的输出, 并结束child
const execa = require('execa');
(async () => {
let child = execa.node('./child.js')
child.on('message', data => {
console.log('parent receive:', data)
console.log('parent stdout:',child.stdout.read().toString())
child.kill()
})
child.send({
msg: 'hello',
})
})()
父成功接受到子传递的消息
parent receive: { msg: 'child hello' }
parent stdout: child receive { msg: 'hello' }
父子进程通讯
child
function fib(n) {
return n < 2 ? n : fib(n - 1) + fib(n - 2)
}
process.on('message', n => {
let st = +new Date()
let list = []
for (let i = 0; i < n; i++)
list.push(fib(i))
let ed = +new Date()
process.send(
{
list,
time: ed - st
}
)
})
parent, 同样的40项, 和之前的没有太多差别, 但是写法上稍微好点
const execa = require('execa');
(async () => {
let st = +new Date()
let list = Array(10).fill(0).map(
() => {
let child = execa.node('./child.js')
child.send(40)
return new Promise(
resolve => {
child.on('message', data => {
child.kill()
resolve(data)
})
}
)
}
)
let times = (await Promise.all(list)).map(i => i.time)
let ed = +new Date()
console.log(ed - st, times)
// 5781 [
// 5312, 5274, 5445,
// 5456, 5364, 5367,
// 5403, 5409, 5357,
// 5326
// ]
})()