链接承诺导致未定义

时间:2014-04-15 04:27:39

标签: javascript jquery angularjs promise jquery-deferred

我在此函数中一直收到未定义的错误。它分为5个单独的函数,我试图在前一个函数完成之后运行,但是使用从前一个函数返回的数据。我可以嵌套所有的回调,但我宁愿使用promises。

var checkedOutReport = function () { 
    var rootSite = window.location.protocol + "//" + window.location.hostname;

    //Create array with each collection site
    function getAllSites (){
        var d = $q.defer();
        var allSites = [];

        $().SPServices({
            operation: "GetAllSubWebCollection",
            completefunc: function (xData,Status){
                var result = $(xData.responseXML);

                result.find('Web').each(function (){
                    var self = $(this);
                    allSites.push({
                        siteTitle: self.attr('Title'),
                        siteUrl: self.attr('Url')   
                    })
                })  
            }
        })
        d.resolve(allSites)
        return d.promise;
    }
    //Get libraries for each siteUrl
    function getSiteLibraries (allSites) {
        var siteCount = allSites.length;
        var listPromise = [];

        //Go through each site and find document libraries 
        for (var i = 0; i < siteCount; i++){
            listPromise[i] = $().SPServices({
                operation: "GetListCollection",
                webURL: allSites[i].siteUrl
            })
        }

        //Promise array contains all lists for each site
        //Get libraries for each site 
        $q.all(listPromise).then(findLibraries(listPromise))
    }
    function findLibraries (promises){
        var d = $q.defer();
        var siteCount = promises.length;
        var allLibraries = [];
        //For each site, find the document libraries
        for (var i = 0; i < siteCount; i++){
            $(promises[i].responseXML).find("List[ServerTemplate='101']").each(function(){
                var self = $(this);
                allLibraries.push({
                    listName = self.attr('Title'),
                    listId = self.attr('ID'),
                    siteUrl = allSites[i].siteUrl
                })
            })
        }
        console.log(allLibraries);
        d.resolve(allLibraries);
        return d.promise;
    }

    //CAML QUERIES
    var cQueryOptions = "<QueryOptions><ViewAttributes Scope='RecursiveAll' IncludeRootFolder='True' /></QueryOptions>",
        cQueryAllCheckedOutDocuments = '<Query><Where><IsNotNull><FieldRef Name="CheckoutUser" /></IsNotNull></Where></Query>',
        cQueryModifiedBySystemAccount = '<Query><Where><Contains><FieldRef Name="Editor" /><Value Type="User">system</Value></Contains></Where></Query>',
        cViewFields = "<ViewFields Properties='True' />";

    //For each library in site collection, find documents which meet criteria 
    function searchLibraries (library) {
        var libraryCount = library.length;
        var itemPromise = [];

        for (var i = 0; i < libraryCount; i++){
            itemPromise[i] = $().SPServices({
                operation: "GetListItems",
                webURL: library[i].siteUrl,
                listName: library[i].listID,
                CAMLViewFields: cViewFields,
                CAMLQuery: cQueryAllCheckedOutDocuments
            })
        }

        $q.all(itemPromise).then(parseSearchResult(itemPromise))
    }
    //Clean up result
    function parseSearchResult(result){
        var d = $q.defer()
        var resultCount = result.length; 
        var returnedFiles = [];
        for(var i = 0; i < resultCount; i++){
            $(result[i].responseXML).SPFilterNode("z:row").each(function (){
                var self = $(this);

                var fileName = self.attr('ows_LinkFilename');
                var fileUrl = self.attr('ows_FileDirRef').split("#");
                var checkedTo = self.attr('ows_LinkCheckedOutTitle');
                var modified = self.attr('ows_Modified');

                returnedFiles.push({
                    fileName: fileName,
                    fileUrl: fileUrl[1],
                    checkedTo: checkedTo,
                    modified: modified
                });
            })
        }
        d.resolve(returnedFiles);
        return d.promise;
    }

    getAllSites()
        .then(
            getSiteLibraries(allSites)
            )
        .then(
            searchLibraries(allLibraries)
            );
}

1 个答案:

答案 0 :(得分:2)

这里有很多问题。我会尽力描述尽可能多的东西。可能还有几个......

d.resolve(allSites)需要位于completefunc回调中,因为您不想在填充allSites之前解析承诺。

getSiteLibraries()searchLibraries()需要回复他们的承诺。

findLibraries()parseSearchResult()没有任何异步代码,因此无需返回promises,只返回结果。

$q.all(listPromise).then(findLibraries(listPromise))实际上会立即执行findLibraries(),只需使用$q.all(listPromise).then(findLibraries)。同样适用于$q.all(itemPromise).then(parseSearchResult(itemPromise))

同样适用于......

getAllSites()
    .then(
        getSiteLibraries(allSites)
        )
    .then(
        searchLibraries(allLibraries)
        );

更改为:

getAllSites()
    .then(
        getSiteLibraries
        )
    .then(
        searchLibraries
        );

应用上述更改......

var checkedOutReport = function () { 
    var rootSite = window.location.protocol + "//" + window.location.hostname;

    //Create array with each collection site
    function getAllSites (){
        var d = $q.defer();
        var allSites = [];

        $().SPServices({
            operation: "GetAllSubWebCollection",
            completefunc: function (xData,Status){
                var result = $(xData.responseXML);

                result.find('Web').each(function (){
                    var self = $(this);
                    allSites.push({
                        siteTitle: self.attr('Title'),
                        siteUrl: self.attr('Url')  
                    })
                })  
                d.resolve(allSites); // resolve only when complete
            }
        });
        return d.promise;
    }
    //Get libraries for each siteUrl
    function getSiteLibraries (allSites) {
        var siteCount = allSites.length;
        var listPromise = [];

        //Go through each site and find document libraries 
        for (var i = 0; i < siteCount; i++){
            listPromise[i] = $().SPServices({
                operation: "GetListCollection",
                webURL: allSites[i].siteUrl
            })
        }

        //Promise array contains all lists for each site
        //Get libraries for each site 
        return $q.all(listPromise).then(findLibraries); // need to return the promise
    }
    function findLibraries (promises){
        var siteCount = promises.length;
        var allLibraries = [];
        //For each site, find the document libraries
        for (var i = 0; i < siteCount; i++){
            $(promises[i].responseXML).find("List[ServerTemplate='101']").each(function(){
                var self = $(this);
                allLibraries.push({
                    listName: self.attr('Title'),
                    listId: self.attr('ID'),
                    siteUrl: allSites[i].siteUrl
                })
            })
        }
        console.log(allLibraries);
        return allLibraries; // don't need a promise here
    }

    //CAML QUERIES
    var cQueryOptions = "<QueryOptions><ViewAttributes Scope='RecursiveAll' IncludeRootFolder='True' /></QueryOptions>",
        cQueryAllCheckedOutDocuments = '<Query><Where><IsNotNull><FieldRef Name="CheckoutUser" /></IsNotNull></Where></Query>',
        cQueryModifiedBySystemAccount = '<Query><Where><Contains><FieldRef Name="Editor" /><Value Type="User">system</Value></Contains></Where></Query>',
        cViewFields = "<ViewFields Properties='True' />";

    //For each library in site collection, find documents which meet criteria 
    function searchLibraries (library) {
        var libraryCount = library.length;
        var itemPromise = [];

        for (var i = 0; i < libraryCount; i++){
            itemPromise[i] = $().SPServices({
                operation: "GetListItems",
                webURL: library[i].siteUrl,
                listName: library[i].listID,
                CAMLViewFields: cViewFields,
                CAMLQuery: cQueryAllCheckedOutDocuments
            })
        }

        return $q.all(itemPromise).then(parseSearchResult); // need to return promise
    }
    //Clean up result
    function parseSearchResult(result){
        var resultCount = result.length; 
        var returnedFiles = [];
        for(var i = 0; i < resultCount; i++){
            $(result[i].responseXML).SPFilterNode("z:row").each(function (){
                var self = $(this);

                var fileName = self.attr('ows_LinkFilename');
                var fileUrl = self.attr('ows_FileDirRef').split("#");
                var checkedTo = self.attr('ows_LinkCheckedOutTitle');
                var modified = self.attr('ows_Modified');

                returnedFiles.push({
                    fileName: fileName,
                    fileUrl: fileUrl[1],
                    checkedTo: checkedTo,
                    modified: modified
                });
            })
        }
        return returnedFiles; // don't need a promise here
    }

    getAllSites()
        .then(
            getSiteLibraries
            )
        .then(
            searchLibraries
            );
}