异步库是否有任何用于处理管道的控制流
Does the async library have any control flow for handling pipelines?
我正在研究异步库,但似乎找不到处理管道的控制流。我只是想知道我是不是错过了什么。
我想实现一个管道。示例:
let pipeline = [];
pipeline.push((input, next) => { next(null, input); });
pipeline.push((input, next) => { next(null, input); });
var pipelineResult = pipelineRunner.run(pipeline, 'sample input', (error, result) => {});
解释:调用了一系列函数。每个函数接收一个input
和一个next
函数。每个函数处理input
并将其作为参数传递给next
函数。作为管道执行的结果,我得到了已处理的input
,或者,如果任何函数调用next
时出错,管道将停止并调用回调。
我想这是一个非常常见的用例,所以我认为async可以做到,但我找不到它。如果你知道有其他库可以达到这样的结果,那也是可以接受的。
您正在查找async.waterfall
函数。
或者,如果您需要一个可以将初始input
传递给的函数,则可以使用多个参数应用asyc.seq
或async.compose
。
我最终自己实现了它,尽管正如@Bergi刚刚展示的那样,async
确实支持它。
/**
* Runs asynchronous pipelines
*/
class PipelineRunner {
/**
* Runs the given pipeline
* @param pipeline - The array of functions that should be executed (middleware)
* @param middlewareArgs - The array of arguments that should be passed in to the middleware
* @param input
* @param next
*/
run(pipeline, middlewareArgs, input, next) {
if (!pipeline) throw Error('''pipeline'' should be truthy');
if (!context) throw Error('''context'' should be truthy');
if (!input) throw Error('''input'' should be truthy');
if (!next) throw Error('''next'' should be truthy');
if (!pipeline.length) throw Error('''pipeline.length'' should be truthy');
let index = 0;
// the link function "binds" every function in the pipeline array together
let link = (error, result) => {
if (error) {
next(error);
return;
}
let nextIndex = index++;
if (nextIndex < pipeline.length) {
let args = [result].concat(middlewareArgs).concat(link);
pipeline[nextIndex].apply(null, args);
}
else {
next(null, result);
}
};
let args = [input].concat(middlewareArgs).concat(link);
pipeline[index++].apply(null, args);
}
}
export default new PipelineRunner();
单元测试:
import chai from 'chai';
import pipelineRunner from '../src/server/lib/pipelines/pipelineRunner';
let assert = chai.assert;
describe('PipelineRunner', () => {
describe('run', function() {
it('Happy path', () => {
let pipeline = [];
pipeline.push((input, next) => { next(null, input); });
pipeline.push((input, next) => { next(null, input); });
pipelineRunner.run(pipeline, [], 'happy', (error, result) => {
assert.strictEqual(result, "happy");
});
});
it('Happy path - with arguments', () => {
let pipeline = [];
pipeline.push((input, someArgument, next) => {
assert.strictEqual(someArgument, 'something that should be passed in');
next(null, input);
});
pipeline.push((input, someArgument, next) => { next(null, input); });
pipelineRunner.run(pipeline, ['something that should be passed in'], 'happy', (error, result) => {
assert.strictEqual(result, "happy");
});
});
it('When something goes wrong', () => {
let pipeline = [];
pipeline.push((input, next) => { next(null, input); });
pipeline.push((input, next) => { next('something went wrong'); });
pipelineRunner.run(pipeline, [], 'happy', (error, result) => {
assert.strictEqual(error, 'something went wrong');
});
});
});
});
相关文章:
- 可以't让我的if语句处理js中的html表单输入
- keyup事件处理程序更改焦点不适用于快速键入
- 如何使用jquery处理php循环通过元素
- 如何检查管道中未定义的项目
- angular.js没有'无法在PhoneGap中处理视图标记
- Webpack/Rect:遵循egghead.io教程,但出现错误:您可能需要一个合适的加载程序来处理此文件类型
- 提示使用服务器端事件处理程序激活JavaScript
- javascript:如何在antlr生成的Lexer中进行错误处理
- 如何编写一个具有公共标头的批处理
- 在同一个服务工作者中处理service-worker.js有任何影响吗
- 如何处理node.js节点mongodb中的连接和查询队列
- 通过命令行/批处理文件打开页面时,将javascript代码注入Google Chrome
- 如何处理10页以上的静态页眉/页脚
- 将事件处理程序绑定到任何可能的事件
- 通过ajax将坐标传递到php服务器端,并在处理后检索到javascript
- 请求管道处理错误
- 如何编写 Node.js 模块来处理传入的管道流
- 异步库是否有任何用于处理管道的控制流
- 如何处理大文件、NodeJS流和管道
- 用lodash对管道进行过滤和处理