JavaScript中的“递归AJAX回调”如何工作?

时间:2012-03-17 05:14:28

标签: javascript ajax

我正在使用Github API来检索有关我的一个repos的数据,并且我遇到了回调函数和递归函数重叠的问题(如附加回调的递归函数)

Here is the script on jsfiddle以及以下内容:

(function () {
    'use strict';

    function makeAJAXCall(hash, cb) {
        $.ajaxSetup({
            accept: 'application/vnd.github.raw',
            dataType: 'jsonp'
        });

        $.ajax({
            url: hash,
            success: function (json) {
                //console.info(json);
                // Time for callback to be executed
                if (cb) {
                    cb(json);
                }
            },
            error: function (error) {
                console.error(error);
                // an error happened, check it out.
                throw error;
            }
        });
    }

    function parseBlob(hash) {
        return makeAJAXCall(hash, function (returnedJSON) {  // no loop as only one entry
            console.log(returnedJSON.data);
            return returnedJSON.data.content;
        });
    }

    function walkTree(hash) {
        var tree = 'https://api.github.com/repos/myusername/SVG-Shapes/git/trees/' + hash;
        return makeAJAXCall(tree, function (objectedJSON) {
            var objectList = [], i, entry;
            for (i = 0;  i < objectedJSON.data.tree.length; i += 1) {
                entry = objectedJSON.data.tree[i];
                //console.debug(entry);
                if (entry.type === 'blob') {
                    if (entry.path.slice(-4) === '.svg') {     // we only want the svg images not the ignore file and README etc
                        //console.info(entry.path)
                        objectList.push(parseBlob(entry.url));
                    }
                } else if (entry.type === 'tree') {
                    objectList.push(walkTree(entry.sha));
                }
            }
            if (cb) {
                console.log(objectList);
                cb(objectList);
            }
            return objectList;
        });
    }

    $(document).ready(function () {
        var returnedObjects = walkTree('master', function (objects) {     // master to start at the top and work our way down
            console.info(objects);
        });
    });
}());

返回的JSON是博客(文件)或树(目录)。如果是树,则再次调用walkTree函数。我不明白回调在这里的表现如何,以及如何获取数据(应该)从函数返回到最底部的最后一个块。

有人可以澄清我应该怎么做吗?

1 个答案:

答案 0 :(得分:4)

Ajax调用通常是异步的。这意味着当你进行ajax调用时,它只是启动ajax调用,并在一段时间后完成。同时,在启动ajax调用之后,其余代码将一直运行直到完成。

然后,稍后当ajax调用完成时,将调用success函数,在您的情况下,回调函数将由success函数调用。重要的是要理解成功函数在makeAJAXCall()函数完成后很久才被调用。

因此,您无法从makeAJAXCall()函数返回ajax数据,因为该函数返回时尚不知道。

事实上,你可以使用ajax调用结果的唯一两个地方是:

  1. 直接在成功处理程序中
  2. 在一些函数中,成功处理程序在你的情况下调用了回调函数。
  3. 因此,回调函数对return returnedJSON.data.content;没有好处。这只是回到ajax基础设施的一些内部部分,什么都不做。该返回值将被丢弃在地板上并丢失。

    相反,您需要在该回调函数中放置任何想要使用returnedJSON.data.content的代码(或通过函数调用将其传递给另一个函数)。

    Ajax是异步的。这意味着在使用ajax时无法进行正常的顺序编程。相反,您必须执行事件驱动编程,在这种情况下,事件是在成功完成ajax调用时调用的回调。所有使用这些ajax结果的工作都需要从成功处理程序或从中调用的回调开始。