如何跳过一个" async.forEachOf"在Node.js的循环迭代 [英] How to Skip a "async.forEachOf" loop iteration in Node.js

查看:1445
本文介绍了如何跳过一个" async.forEachOf"在Node.js的循环迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个 async.waterfall 是内嵌套一个 async.forEachOfLimit 回路如图低于code。

问:如何跳过的迭代 async.forEachLimit 当code正在执行内的台阶 async.waterfall ?换句话说,打出来的 async.waterfall 键,返回到 async.forEachLimit 。我在code注释的位置,应该不会出现此检查

目前的code给出了一个错误回调已经被调用。

另外,如果我使用返回回调()的CB()时,我想打破出 async.waterfall ,不会发生错误,但它不会被跳过。

  VAR异步=要求(异步)
VAR用户= ['一','B','C']async.forEachOfLimit(用户,1,功能(用户,指数,CB){    的console.log(索引+:+用户)    async.waterfall([
        函数(回调){
            回调(NULL);
        },
        函数(回调){
            //跳过async.forEAchOfLimit迭代时指数== 1
            如果(指数== 1)
                CB()            回调(NULL);
        }
    ],功能(错了,结果){
        的console.log(索引+:做)
        CB()
    });},函数(){
    的console.log('ALL做')
})

错误

  0:一
0:完成
1:乙
2:C
1:完成/Users/x/test/node_modules/async/lib/async.js:43
            如果(FN ===空)抛出新的错误(回调已经被称为);
                                   ^
错误:回调已被调用。

所需的输出

  0:一
0:完成
1:乙
2:C
2:完成
全做完了


返回回调()

  VAR异步=要求(异步)
VAR用户= ['一','B','C']async.forEachOfLimit(用户,1,功能(用户,指数,CB){    的console.log(索引+:+用户)    async.waterfall([
        函数(回调){
            回调(NULL);
        },
        函数(回调){
            //跳过async.forEAchOfLimit迭代时指数== 1
            如果(指数== 1)
                返回回调()            回调(NULL);
        }
    ],功能(错了,结果){
        的console.log(索引+:做)
        CB()
    });},函数(){
    的console.log('ALL做')
})

输出

没有打出去......

  0:一
0:完成
1:乙
1:完成
2:C
2:完成
全做完了


解决方案

在你的第一个解决方案时,指数匹配1, CB 被调用了两次,这就是为什么你一直得到回调已经被称为错误。虽然你叫forEachOfLimit回调 CB ,您的code不停止执行,并调用回调函数。在回调函数 CB 执行一次。

  VAR异步=要求(异步)
VAR用户= ['一','B','C']async.forEachOfLimit(用户,1,功能(用户,指数,CB){    的console.log(索引+:+用户)    async.waterfall([
        函数(回调){
            回调(NULL);
        },
        函数(回调){
            //跳过async.forEAchOfLimit迭代时指数== 1
            如果(指数== 1)
                CB()//首先回拨电话            回调(NULL);
        }
    ],功能(错了,结果){
        的console.log(索引+:做)
        CB()//第二回拨电话
    });},函数(){
    的console.log('ALL做')
})

在第二个解决办法,如果指数匹配1,它调用不带参数的回调,并跳过调用带有null参数的回调。仍然没有摆脱瀑布。

要使用的瀑布,你有两个选择解决您的问题。


  1. 呼叫瀑布的方法回调一个错误的说法,这爆发的瀑布,比处理此错误在瀑布的回调。

      VAR异步=要求(异步)
    VAR用户= ['一','B','C']async.forEachOfLimit(用户,1,功能(用户,指数,CB){    的console.log(索引+:+用户)    async.waterfall([
            函数(回调){
                回调(NULL);
            },
            函数(回调){
                //跳过async.forEAchOfLimit迭代时指数== 1
                如果(指数== 1)
                    返回回调(新的错误(指数等于1'));            回调(NULL);
            }
        ],功能(错了,结果){
            的console.log(索引+:做)        如果(err.message =='指数等于1'){
                ERR = NULL; //如果要继续执行forEachOfLimit没有错误必须传递给CB
            }        CB(ERR,结果);
        });},函数(){
        的console.log('ALL做')
    });


  2. 在各waterfalled方法的开头跳过code的休息,立即调用回调(这是你的第二次尝试做的事情)

      VAR异步=要求(异步)
    VAR用户= ['一','B','C']async.forEachOfLimit(用户,1,功能(用户,指数,CB){    的console.log(索引+:+用户)    async.waterfall([
            函数(回调){
                回调(NULL);
            },
            函数(回调){
                //立即跳过瀑布方法的其余部分的执行
                如果(指数== 1)
                    返回回调()            //一些额外的code在这里            回调(NULL);
            }
        ],功能(错了,结果){
            的console.log(索引+:做)
            CB()
        });},函数(){
        的console.log('ALL做')
    })


A async.waterfall is nested within a async.forEachOfLimit loop as shown in the code below.

Question: How do you skip an iteration of async.forEachLimit when the code is executing a step inside async.waterfall? In other words, break out of async.waterfall and back into async.forEachLimit. I have commented the location in the code where this check should occur

The current code gives an error Callback was already called.

Also, if i use a return callback() in place of cb() when I want to break out of async.waterfall, no error occurs but it is not skipped.

var async = require('async')
var users = ['a','b','c']

async.forEachOfLimit(users, 1, function(user, index, cb) {

    console.log(index + ': ' + user)

    async.waterfall([
        function(callback) {
            callback(null);
        },
        function(callback) {
            // Skip async.forEAchOfLimit iteration when index == 1
            if(index == 1)
                cb()

            callback(null);
        }
    ], function (err, result) {
        console.log(index + ": done")
        cb()
    });

}, function() {
    console.log('ALL done')
})

Error

0: a
0: done
1: b
2: c
1: done

/Users/x/test/node_modules/async/lib/async.js:43
            if (fn === null) throw new Error("Callback was already called.");
                                   ^
Error: Callback was already called.

Desired Output

0: a
0: done
1: b
2: c
2: done
ALL done


Using return callback()

var async = require('async')
var users = ['a','b','c']

async.forEachOfLimit(users, 1, function(user, index, cb) {

    console.log(index + ': ' + user)

    async.waterfall([
        function(callback) {
            callback(null);
        },
        function(callback) {
            // Skip async.forEAchOfLimit iteration when index == 1
            if(index == 1)
                return callback()

            callback(null);
        }
    ], function (err, result) {
        console.log(index + ": done")
        cb()
    });

}, function() {
    console.log('ALL done')
})

Output

Doesn't break out...

0: a
0: done
1: b
1: done
2: c
2: done
ALL done

解决方案

In your first solution when index matches 1, cb is called twice, that is why you keep getting Callback was already called error. Although you call forEachOfLimit callback cb, your code doesn't stop execution and calls callback. In callback function cb is executed one more time.

var async = require('async')
var users = ['a','b','c']

async.forEachOfLimit(users, 1, function(user, index, cb) {

    console.log(index + ': ' + user)

    async.waterfall([
        function(callback) {
            callback(null);
        },
        function(callback) {
            // Skip async.forEAchOfLimit iteration when index == 1
            if(index == 1)
                cb() // First callback call

            callback(null);
        }
    ], function (err, result) {
        console.log(index + ": done")
        cb() // Second callback call
    });

}, function() {
    console.log('ALL done')
})

In second solution if index matches 1, it calls callback with no arguments and skips calling callback with null argument. Still doesn't break out of waterfall.

To solve your problem using waterfall you have two options.

  1. Call waterfall's method callback with an error argument, which breaks out of waterfall and than handle this error in waterfall's callback.

    var async = require('async')
    var users = ['a','b','c']
    
    async.forEachOfLimit(users, 1, function(user, index, cb) {
    
        console.log(index + ': ' + user)
    
        async.waterfall([
            function(callback) {
                callback(null);
            },
            function(callback) {
                // Skip async.forEAchOfLimit iteration when index == 1
                if(index == 1)
                    return callback(new Error('Index equals 1'));
    
                callback(null);
            }
        ], function (err, result) {
            console.log(index + ": done")
    
            if(err.message == 'Index equals 1') {
                err = null; // If you want to continue executing forEachOfLimit no error must be passed to cb
            }
    
            cb(err, result);
        });
    
    }, function() {
        console.log('ALL done')
    });
    

  2. In the beginning of each waterfalled method skip the rest of the code and call callback immediately (which is what you've done in second attempt)

    var async = require('async')
    var users = ['a','b','c']
    
    async.forEachOfLimit(users, 1, function(user, index, cb) {
    
        console.log(index + ': ' + user)
    
        async.waterfall([
            function(callback) {
                callback(null);
            },
            function(callback) {
                // Skip execution of the rest of waterfall method immediately
                if(index == 1)
                    return callback()
    
                // Some additional code here
    
                callback(null);
            }
        ], function (err, result) {
            console.log(index + ": done")
            cb()
        });
    
    }, function() {
        console.log('ALL done')
    })
    

这篇关于如何跳过一个" async.forEachOf"在Node.js的循环迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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