NodeJS:在for循环中调用回调函数 [英] NodeJS: invoking callback function inside a for loop

查看:385
本文介绍了NodeJS:在for循环中调用回调函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我试图调用一个函数,其中一个循环正在运行,其中存在许多回调函数(回调地狱)..如下所示:

Basically, I am trying to call a function, where a loop is running inside of which many callback function are present (callback hell).. as below:

for(var i=0;i<data.id.length;i++)
{
    DAO.getUserById(data.id[i],function(err,resp1)
    {
       /* some other work based on resp1 */
       DAO.getOtherData(resp1.username,resp1.userId,function(err,resp2)
       {
           /* similary some other work*/
       });
    });
}  

我的应用程序中的多个位置都有相同的模式,有一段时间我遇到了回调问题,for循环结束,但回调没有给出响应,似乎DAO方法已被调用但仍在等待响应。
有没有优化的方法来克服这个问题?

I have same pattern at several location in my app, and some time I faced issue with the callback, that for loop get over, but callback do not give response, that seems like DAO method has been called up but still waiting for response. Is there any optimized way, to overcome this issue ?

很高兴知道是否有一些javascript编码模式可以解决这个问题。(除了任何第三方库)谢谢

It would be nice to know if there is some javascript coding pattern available to overcome this issue.(other than any 3rd party library) Thanks

推荐答案

你听说过Deferreds还是Promises?我认为这就是你要找的东西。在它的基本形式中,它基本上是一个有两个处理程序的对象。一个用于失败,一个用于成功。

Have you heard about Deferreds or Promises? I think that's what you're looking for. In it's basic form it's basically a object which has two handler. One for failure and one for success.

但是还有其他辅助函数,例如然后 时让你以更易读的方式链接函数。请查看q或 jQuery 实现。有关非常好的介绍,请阅读异步JavaScript一书。

But there are other helper functions like then or when which let you chain the functions in a more readable way. Have look at q or the jQuery implementation. For a very good introduction read the book Async JavaScript.

编辑:/

我做了一些工作示例为您 js fiddle

I did a little working example as js fiddle for you.

    var data = { id : [] };

    for(var i = 0; i < 10; i++) {
        data.id.push(i);
    }

    // DAO definition
    var DAO = {
        getUserById : function(id) {
            var deferred = $.Deferred();

            setTimeout(function() { 
                var isError = Math.floor(Math.random()*11) > 5;

                if(isError) {
                    deferred.reject("WOW - Much Handler - So error");
                } else {
                    deferred.resolve({
                        username :  'Max',
                        userId : id
                    }); 
                }
            }, 50);

            return deferred.promise();
        },

        getOtherData : function(username, userId) {
            var deferred = $.Deferred();

            setTimeout(function() {
                deferred.resolve((username + ' id: ' + userId));
            }, 20);

            return deferred.promise();
        }
    };



    function printResult(res) {
        $('#result').html($('#result').html() + '<br />' + res);
    };

    // DAO usage

    for(var i=0;i<data.id.length;i++)
    {
        DAO.getUserById(data.id[i])
        .done(function(res) {
            DAO.getOtherData(res.username, res.userId).done(function(result) {
                printResult(result);
            });
        })
        .fail(function(res) {
            printResult(res);
        });
    }

这方面的巨大优势是双重的:

The great advantage of that is twofold:


  1. 您可以免费获得错误处理程序代码和结果处理程序代码

  2. 它可以防止您嵌套地狱。 (回调,回调,回调......)由于延迟,你可以将实际逻辑输出。

  3. 同步回调变得非常简单,因为您只需要使用

  1. You get seperation of error handler code and result handler code for free
  2. It prevents you from nesting hell. (callbacks, in callbacks, in callbacks ...) Due to the deferreds you're able to factore the actual logic out.
  3. Synchronizing of callbacks gets very easy because you only need to use when.

我使用了jQuerys Deferreds,因为jsFiddle在下拉框中有jquery。你可以使用你想要的任何实现。

I used jQuerys Deferreds because jsFiddle has jquery in a dropdown box. You could use any implementation you want.

当你有了实现它的概念时,自己不应该太难。

When you got the concept implementing it yourself shouldn't be too hard.

这篇关于NodeJS:在for循环中调用回调函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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