避免多个流的回调地狱 [英] Avoiding callback hell with multiple streams

查看:28
本文介绍了避免多个流的回调地狱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我打开多个流并且必须获得一个绝对的 end 事件来完成逻辑时,如何避免使用类似递归的结构.

How can I avoid using a recursion like structure when I got several streams to open and I have to get an absolute end event to finish the logic.

var someArray = ['file1', 'file2', 'file3'];

someArray.forEach(function( file ) {
    fs
        .createReadStream( file )
        .pipe( /* do some stuff */ )
        .on('data', function( usageInfo ) {

            // done?

        });
}

我有几个文件,我必须通过 tp 一些进程.如何设置一个事件来告诉我所有这些都何时完成?目前我得到的是每个 end 事件.

I got several files I have to pipe through tp some processes. How can I setup an event that tells me when all of them are done? Currently what I'm getting is each end event individually.

我绝对可以同时启动每个流.我只需要以某种方式收集结尾?

I can absolutely start each stream at the same time. I just need to somehow collect the end?

我可以为每个 end 事件调用一个函数调用并计算它...虽然听起来很hacky?...

I could invoke a function call for each end event and count it... that sounds hacky though?...

我觉得有一种方法可以通过 Promise 做到这一点,但我不知道该怎么做.

I feel like there is a way to do this with promises but I don't know how.

推荐答案

我觉得有一种方法可以通过 Promise 做到这一点,但我不知道该怎么做.

I feel like there is a way to do this with promises but I don't know how.

是的,有.由于承诺确实表示异步值,您将获得一个流结束的承诺:

Yes, there is. As promises do represent asynchronous values, you'd get a promise for the end of one stream:

var p = new Promise(function(resolve, reject) {
    fs.createReadStream(file)
    .on('error', reject)
    .pipe(/* do some stuff */)
    .on('end', resolve)
    .on('error', reject); // call reject(err) when something goes wrong
});

它可以像 p.then(functio(usageInfo) { console.log("stream end"); }) 一样使用.

It could be used like p.then(functio(usageInfo) { console.log("stream ended"); }).

现在,如果您创建多个承诺,其中一个用于数组中的文件名,则所有流将并行运行并在完成后解析各自的承诺.然后你可以使用 Promise.all 收集 - 读取await" - 将每个结果的所有结果转换为一组结果的新承诺.

Now if you create multiple promises, one for filename in your array, all the streams will run in parallel and resolve their respective promise when done. You then can use Promise.all to collect - read "await" - all the results from each of them into a new promise for an array of results.

var promises = ['file1', 'file2', 'file3'].map(function(file) {
    return new Promise(function(resolve, reject) {
        …
    });
});
Promise.all(promises).then(function(usageInfos) {
    console.log("all of them done", usageInfos),
}, function(err) {
    console.error("(At least) one of them failed", err);
});

这篇关于避免多个流的回调地狱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆