gpt4 book ai didi

javascript - Node 中并发事件 ('map-reduce' ) 的惯用同步?

转载 作者:行者123 更新时间:2023-11-30 08:31:11 26 4
gpt4 key购买 nike

编辑

多亏了答案,我有了一个工作版本。问题末尾的代码;感谢@estus 和@Jared 的帮助。

原始问题

我正在努力学习 Node,并尝试掌握并发性。从一个简单的例子开始:给定两个文件的名称,确定哪个更大。常规(顺序)解决方案:

var fs = require('fs');

var fname1=process.argv[2]
var fname2=process.argv[3]

var stats1 = fs.statSync(fname1)
size1=stats1["size"]

var stats2 = fs.statSync(fname2)
size2=stats2["size"]

if(size1 > size2) {
console.log(fname1 + " is bigger")
} else if (size2 > size1) {
console.log(fname2 + " is bigger")
} else {
console.log("The files are the same size")
}

现在假设我想并行统计文件*。我可以转换代码以使用异步 stat 函数:

var fs = require('fs');

var fname1=process.argv[2]
var fname2=process.argv[3]

fs.stat(fname1, function doneReading(err, stats) {
size1=stats["size"]
fs.stat(fname2, function doneReading(err, stats) {
size2=stats["size"]
if(size1 > size2) {
console.log(fname1 + " is bigger")
} else if (size2 > size1) {
console.log(fname2 + " is bigger")
} else {
console.log("The files are the same size")
}
})
})

但是:

  1. 可读性较差;
  2. 如果我想比较 >2 个文件,它不会很好地扩展;
  3. 不确定它是否会并行统计文件(我不清楚 atm 后台线程是如何工作的)。

那么,具体来说,惯用的方法是什么:

  1. 同时产生多个 Action ,然后
  2. 在所有完成后使用他们的综合结果?

也许 promises 可能是一个候选人? Promise.all 看起来像是等待所有 promise 的方式,但不清楚如何实际使用它们的结果。

谢谢。

解决方案

'use strict';

const co = require('co');
const fs = require('fs-promise');

var fname1=process.argv[2]
var fname2=process.argv[3]

co(function* () {
let res = yield [fs.stat(fname1), fs.stat(fname2)];
let size1 = res[0]["size"]
let size2 = res[1]["size"]
if(size1 > size2) {
console.log(fname1 + " is bigger")
} else if (size2 > size1) {
console.log(fname2 + " is bigger")
} else {
console.log("The files are the same size")
}
})

它非常可读、简洁,并且完全没有回调脏话。并且易于扩展以比较 n 个文件。

--

*是的,我知道在这种情况下没有必要这样做;目的是通过一个简单的例子来理解模式。

最佳答案

fs.stat(fname1, function doneReading(err, stats) {
...
fs.stat(fname2, function doneReading(err, stats) {
...

仍然是顺序的而不是并行的,与fs.statSync的区别在于fs.stat是非阻塞的。

现代 Node 中建议的“可读”方法是 promises 和 cofs.stat 可以被 promise (使用 pify 或 Bluebird 的 Promise.promisify/Promise.promisifyAll)。或者可以使用一些现有的 promisified fs 包,比如 fs-promise

上述代码的顺序和非阻塞替代方案可能如下所示:

'use strict';

const co = require('co');
const fs = require('fs-promise');

co(function* () {
let stat1 = yield fs.stat(fname1);
let stat2 = yield fs.stat(fname2);
...
});

如果我们想让它并行,Promise.all 介入:

co(function* () {
let [stat1, stat2] = yield [fs.stat(fname1), fs.stat(fname2)];
// a shortcut for
// let [stat1, stat2] = yield Promise.all([fs.stat(fname1), fs.stat(fname2)]);
...
});

关于javascript - Node 中并发事件 ('map-reduce' ) 的惯用同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37834087/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com