简体   繁体   English

多个条件异步递归函数和jQuery Promise

[英]Multiple conditional asynchronous recursive functions and jQuery promises

I have a complicate recursive javascript function that worked very well until I needed to start using asynchronous functions (jQuery.ajax in this case). 我有一个复杂的递归javascript函数,在我需要开始使用异步函数(在这种情况下为jQuery.ajax)之前,它可以很好地工作。 I have included some psuedo-code below that gives the gist of the situation. 我在下面添加了一些伪代码,以说明情况。 I would like to implement this code using promises (instead of the current callbacks), but can't work out how to do deal with the recursion and the multiple conditional ajax calls. 我想使用Promise(而不是当前的回调)来实现此代码,但无法解决如何处理递归和多个条件Ajax调用。 If I understand promises correctly they allow you to act on the return of an asynchronous call, but how do I deal with the situation below? 如果我正确理解了promise,它们将允许您对异步调用的返回进行操作,但是如何处理以下情况?

function wrapperFunction(success,error) {
    var level = 0;
    result = [];

    var innerFunction = function(info,result,success,error) {
        level++;

        jQuery.ajax({
            url: 'baseurl1' + info,
            success: parseData,
            error: error
        });

        function parseData(data) {
            data.forEach( function(item) {
                result.push(item.something);

                if ( item.info ) {
                    innerFunction(item.info, result, success, error);
                }
            });

            if ( data.condition ) {
                jQuery.ajax({
                    url: 'baseurl2' + info,
                    success: parseData2,
                    error: error
                });
            }

            function parseData2(data2) {
                data2.forEach(function(item2) {
                    if ( item2.condition ) {
                        jQuery.ajax({
                            url: 'baseurl3' + info,
                            success: parseData3,
                            error: error
                        });
                    }
                });
                function parseData3(data3) {
                    if ( data3.condition ) {
                        jQuery.ajax({
                            url: 'baseurl4' + info,
                            success: parseData4,
                            error: error
                        });
                    }
                    function parseData4(data) {
                        result.push(data2.something + data4.something);
                    }
                }
            }

            level--;
            if (level == 0 && success) {
                success(result);
            }
        }

    }

    innerFunction('rootinfo', result, success, error);   
}   

wrapperFunction(
    function(data) {
        // process success
    },
    function(err) {
        // handle errors
    }
}

As I said already, this is only pseudo code. 正如我已经说过的,这只是伪代码。 I initially extracted it from my real code to see if I could get my head around the actual structure. 最初,我从实际代码中提取了它,以查看是否可以深入了解实际结构。 I know it works if the ajax calls where synchronous, but now they are asynchronous it only sometimes works (depending on how quickly the calls return). 我知道,如果ajax调用在同步的地方起作用,但是现在它们是异步的,它有时仅起作用(取决于调用返回的速度)。

How do I implement this situation using promises? 如何使用诺言实现这种情况?

EDIT 编辑

I have just worked out how to use promises to serialise everything, and though that is one way to wait for everything to finish I rather run multiple calls in parallel and then find a way to wait for everything to finish. 我刚刚想出了如何使用Promise序列化所有内容的方法,尽管那是等待所有操作完成的一种方法,我宁愿并行运行多个调用,然后找到一种等待所有操作完成的方法。 I know this is possible with promises, but I don't know how. 我知道这是可以实现的,但是我不知道如何做到。

I have got it working, with the help of Sandeep Nayak (see comments above). 在Sandeep Nayak的帮助下,它已经开始工作(请参阅上面的评论)。 I thought I post the working version of the pseudo code for anyone coming across this post with a similar problem. 我以为我为遇到类似问题的任何人发布了伪代码的工作版本。

I have essentially added two levels of promises (outer and inner), where the outer promise does get resolved if all inner promises are resolved. 我实质上增加了两个级别的承诺(外部和内部),如果所有内部承诺都得到解决,则外部承诺会得到解决。 There is probably scope for tidying up the code, but it works as it stands. 整理代码可能有一定的余地,但它可以正常工作。

function wrapperFunction(success,error) {
    var level = 0;
    var result = [];
    var outerPromises = [];

    var innerFunction = function(info,result,success,error) {
        var outerPromise = new jQuery.Deferred();
        outerPromises.push( outerPromise );

        level++;

        jQuery.ajax({
            url: 'baseurl1' + info,
            success: parseData,
            error: error
        });

        function parseData(data) {
            data.forEach( function(item) {
                result.push(item.something);

                if ( item.info ) {
                    innerFunction(item.info, result, success, error);
                }
            });

            if ( data.condition ) {
                jQuery.ajax({
                    url: 'baseurl2' + info,
                    success: parseData2,
                    error: error
                });
            } else {
                outerPromise.resolve();
            }

            function parseData2(data2) {
                var innerPromises = [];

                data2.forEach(function(item2) {
                    var innerPromise = new jQuery.Deferred();
                    innerPromises.push( innerPromise );

                    if ( item2.condition ) {
                        jQuery.ajax({
                            url: 'baseurl3' + info,
                            success: parseData3,
                            error: error
                        });
                    } else {
                        innerPromise.resolve();
                    }

                    function parseData3(data3) {
                        if ( data3.condition ) {
                            jQuery.ajax({
                                url: 'baseurl4' + info,
                                success: parseData4,
                                error: error
                            });
                        } else {
                            innerPromise.resolve();
                        }
                        function parseData4(data) {
                            result.push(data2.something + data4.something);

                            innerPromise.resolve();
                        }
                    }
                });

                jQuery.when.apply(undefined, innerPromises).then( function() { outerPromise.resolve(); } );
            }

            level--;
            if (level == 0 && success) {
                jQuery.when.apply(undefined, outerPromises).then( function() { success(result); } );
            }
        }

    }

    innerFunction('rootinfo', result, success, error);   
}   

wrapperFunction(
    function(data) {
        // process success
    },
    function(err) {
        // handle errors
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM