【问题标题】:setTimeout in nodejs - for loopsnodejs中的setTimeout - for循环
【发布时间】:2014-12-10 05:18:06
【问题描述】:

我查看了这篇文章:setTimeout in Node.js loop,希望它能解决我的问题,并且在某种程度上它已经解决了。但是,我遇到了一个我无法自行解决的新问题。

在过去的几个小时里,我一直在尝试解决这个问题,但我没有运气。这是我所拥有的:

超时函数中需要调用的函数:

function searchLDAP(i, app, userUID){
    app.process_args(userUID[i]);
}

这是代码中不能正常工作的部分。该代码适用于第一次迭代 (userUID[0]),但是当它尝试递归时,i 变为 undefined

function doSetTimeout(i, count, app, userUID) {
    if(i == count - 1){ callback(); }    
    searchLDAP(i, app, userUID);

    ++i;
    setTimeout(doSetTimeout, 2000);
}

我正在使用节点的异步模块

async.series([
    function(callback) {
        app.readLines(input, callback); // userUID is and array that 
                                        // is returned from this function
    },
    function() {
        var count = userUID.length;
        var i = 0;
        doSetTimeout(i, count, app, userUID);
    }
    ], function(err) {
        console.log('all functions complete');
});

提前谢谢你

-帕特里克

【问题讨论】:

    标签: javascript node.js asynchronous


    【解决方案1】:

    使用setTimeout,您只能命令应该调用哪个函数,但不传递函数应该使用的参数集。这是解决此问题的一种可能方法:

    function doSetTimeout(i, count, app, userUID) {
        if (i == count - 1) { 
          return; // you should stop the recursion
        }
    
        searchLDAP(i, app, userUID);
    
        setTimeout(function() {
          doSetTimeout(i + 1, count, app, userUID);
        }, 2000);
    }
    

    【讨论】:

    • 当我这样做时,它只返回数组中最后一个元素的信息。例如,如果我有 5 个 userUIDs 需要通过,它会调用 searchLDAP()5 次,但是它只会使用 userUID[4],而不是 userUID[0] 然后是 userUID[1] ... 等
    • 应用程序return的信息究竟如何?你问的不是用setTimeout解决问题吗?
    • 大声笑,我误读了你的答案。有效。谢谢您的帮助。我忘记在调用doSetTimeout之前输入function(){...}
    • 没问题,没关系。事实上,忘记如何结束递归以及如何开始递归都太容易了。 )
    【解决方案2】:

    作为raina77ow 的答案的替代方案,您还可以像这样更好地使用异步(并显着降低复杂性和代码行数):

    app.readLines(input, function(err, users) {
        async.each(users, function(user, next) {
            app.process_args(user);
            next();
        }, function(err) {
            console.log('all functions complete');
        });
    });
    

    这将遍历您的每个用户(您发布的 userUID 数组),并将值传递给函数。无需自己跟踪 i 的价值。这不受速率限制,也没有 setTimeout ,这仅在您的 process_args 方法无法处理并发调用时才需要。如果您需要确保一次只调用一个 app.process_args,您可以使用 eachSeries:

    app.readLines(input, function(err, users) {
        async.eachSeries(users, function(user, next) {
            app.process_args(user);
            next();
        }, function(err) {
            console.log('all functions complete');
        });
    });
    

    如果出于某种原因您真的需要在两次通话之间延迟两秒,您可以执行以下操作:

    app.readLines(input, function(err, users) {
        async.eachSeries(users, function(user, next) {
            setTimeout(function() {
                app.process_args(user);
                next();
            }, 2000);
        }, function(err) {
            console.log('all functions complete');
        });
    });
    

    【讨论】:

    • 谢谢。我也打算试试这个方法。
    猜你喜欢
    • 1970-01-01
    • 2019-08-21
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 2014-05-18
    相关资源
    最近更新 更多