我正在使用highland.js
使用流处理文件来读取两个分隔符之间的内容。我还使用async.js
按顺序运行一系列http请求。
理想情况下,我希望将输出x
作为第一个函数从高地传递到async
系列(链),以便为从流中提取的每个块执行HTTP请求。
这可能吗?如果是这样,怎么能实现呢?
var async = require('async');
var _ = require('highland');
_(fs.createReadStream(files[0], { encoding: 'utf8' }))
.splitBy('-----BEGIN-----\n')
.splitBy('\n-----END-----\n')
.filter(chunk => chunk !== '')
.each(function (x) {
}).done(function () {
async.series([
function(callback) {
setTimeout(function() {
console.log('Task 1');
callback(null, 1);
}, 300);
},
function(callback) {
setTimeout(function() {
console.log('Task 2');
callback(null, 2);
}, 200);
},
], function(error, results) {
console.log(results);
});
});;
答案 0 :(得分:1)
您可以删除对each
和done
的来电。过滤后,您可以使用.toArray(callback)
进行跟进。回调传递一个包含高地结果的数组。你可能会像这样重构
var Q = require('q');
var _ = require('highland');
_(fs.createReadStream(files[0], { encoding: 'utf8' }))
.splitBy('-----BEGIN-----\n')
.splitBy('\n-----END-----\n')
.filter(chunk => chunk !== '')
.each(asyncTasks);
function asyncTasks(x) { // here, x will be each of the results from highland
async.series([
// do something with x results
function(callback) {
console.log('Task 1');
callback(null, 1);
},
// do something else with x results
function(callback) {
console.log('Task 2');
callback(null, 2);
},
], function(error, results) {
console.log(results);
});
}
here是toArray
文档的链接。 toArray
消费流,就像done
一样。如果您有任何问题,请告诉我。
虽然老实说,我认为你最好不要使用promises。虽然它的一部分只是个人偏好,但部分原因是它使代码更具可读性。从what I've read开始,async比promises更高效,但关于promises的好处是你可以将结果从一个函数传递给下一个函数。因此,在您的示例中,您可以在第一部分中对x
执行一些操作,然后将修改后的结果传递给下一个函数,以及下一个函数,依此类推。当您使用async.series
时,您可以通过致电callback(null, result)
来完成每项功能,但是当您获得所有功能时,您将无法获得结果,直到您完成系列的最后所有对callback
的调用的结果。现在,您始终可以将结果保存到async.series之外的某个变量,但这会使您的代码变得更加混乱。如果你想用promises重写它,它看起来如下。我在这里使用q
,但它只是您可以使用的许多promise库之一。
var async = require('async');
var _ = require('highland');
_(fs.createReadStream(files[0], { encoding: 'utf8' }))
.splitBy('-----BEGIN-----\n')
.splitBy('\n-----END-----\n')
.filter(chunk => chunk !== '')
.each(asyncTasks);
function asyncTasks(x) { // here, x will be an array of the results from highland
return asyncTask1(x)
.then(asyncTask2)
.then(asyncTask3)
}
function asyncTask1(x) {
var deferred = Q.defer();
// do some stuff
if (// some error condition) {
deferred.reject();
} else {
deferred.resolve(x); // or pass along some modified version of x
}
return deferred.promise;
}
function asyncTask2(x) {
// same structure as above
}
function asyncTask3(x) {
// same structure as above
}
现在,一些异步API已经开始返回promises,除了接受回调,或者有时代替。所以舒服一点是件好事。承诺是非常有用的。您可以详细了解他们here和here。