简体   繁体   中英

How to know when a long series of async calls is finished in AngularJS?

I have a service SQLService on my PhoneGap/AngularJS app that runs when the app is loading. It iterates through a long array of Guidelines , and makes a DB transaction for each one. How can I signal that the final transaction has been completed?

What I want to have happen is something like:

 In the controller, call `SQLService.ParseJSON`
    ParseJSON calls `generateIntersectionSnippets`
      `generateIntersectionSnippets` makes multiple calls to `getKeywordInCategory``
        When the final call to getKeywordInCategory is called, resolve the whole chain
 SQLService.ParseJSON is complete, fire `.then`

I really don't understand how to combine the multiple asynchronous calls here. ParseJSON returns a promise which will be resolved when generateIntersectionSnippets() is completed, but generateIntersectionSnippets() makes multiple calls to getKeywordInCategory which also returns promises.

Here's a simplified version of what's not working (apologies for any misplaced brackets, this is very stripped down).

What I want to happen is for $scope.ready = 2 to run at the completion of all of the transactions. Right now, it runs as soon as the program has looped through generateIntersectionSnippets once.

in the controller :

 SQLService.parseJSON().then(function(d) {
            console.log("finished parsing JSON")
            $scope.ready = 2;
            });

Service :

 .factory('SQLService', ['$q',
    function ($q) {

   function parseJSON() {
            var deferred = $q.defer();

                function generateIntersectionSnippets(guideline, index) {
                    var snippet_self, snippet_other;

                    for (var i = 0; i < guideline.intersections.length; i++) {


                            snippet_self = getKeywordInCategory(guideline.line_id, snippets.keyword).then(function() {
                                //Should something go here?
                            });

                            snippet_other = getKeywordInCategory(guideline.intersections[i].line_id, snippets.keyword).then(function() {
                                //Should something go here?
                            });

                        }


                    }

               deferred.resolve(); //Is fired before the transactions above are complete

            }

            generateIntersectionSnippets();

            return deferred.promise;

  } //End ParseJSON

  function getKeywordInCategory(keyword, category) {
            var deferred = $q.defer();

            var query = "SELECT category, id, chapter, header, snippet(guidelines, '<b>', '</b>', '...', '-1', '-24' ) AS snip FROM guidelines WHERE content MATCH '" + keyword + "' AND id='" + category + "';",
                results = [];

            db.transaction(function(transaction) {
                transaction.executeSql(query, [],
                    function(transaction, result) {
                        if (result != null && result.rows != null) {
                            for (var i = 0; i < result.rows.length; i++) {

                                var row = result.rows.item(i);
                                results.push(row);
                            }
                        }
                    },defaultErrorHandler);
                    deferred.resolve(responses);
            },defaultErrorHandler,defaultNullHandler);

            return deferred.promise;

        }




  return {
            parseJSON : parseJSON
        };
  }]);

I'd appreciate any guidance on what the correct model is to doing a chain of promises that includes an iteration across multiple async transactions- I know that how I have it right now is not correct at all.

You can use $q.all() to wait for a list of promises to be resolved.

function parseJSON() {
    var deferred = $q.defer();
    var promiseList = [];

    for (var i = 0; i < guideline.intersections.length; i++) {
        promiseList.push(getKeywordInCategory(guideline.line_id, snippets.keyword));
        promiseList.push(getKeywordInCategory(guideline.intersections[i].line_id, snippets.keyword));
    }

    $q.all(promiseList).then(function() {
        deferred.resolve();
    });

    return deferred.promise;

} //End ParseJSON

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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