Q -在调用下一个操作之前等待操作完成



在数据上下文中的primeData调用中,有四个对后端Web API服务的查询:

function primeData(forceRefresh) {
    return (getLookups(forceRefresh) // this needs to complete before moving on
              .then(success))
              .then(model.initialize(datacontext)) // depends on getLookups
              .then(getDatasetOne()) // depends on model.initialize
              .then(getDataSetTwo()) // depends on model.initialize
              .then(getNonDependantDataset); // doesn't depend on previous calls
    function success(data) {
       if (!initialized) {
         datacontext.lookups = data.results[0];
         initialized = true;
       } else {
         datacontext.lookups = {
           teams: getLocal('Teams', 'id'),
           // other lookup values here                       
          };
       }
       // should I call model.initialize(datacontext) here??
    }
}

查询2和3 (getDatasetOne()和getDatasetTwo())依赖于模型。initialize——它依赖于第一个查询的结果(getLookups())。我想了解如何确保这种模式。在getlookup成功完成之前不会调用initialize—并确保在模型初始化之前不会调用getDatasetOne/Two。我已经尽可能地减少/简化了代码,以显示完整的画面。很明显,我不理解Q.任何帮助都会非常感激。

控制器:

'use strict';
app.controller('HomeController',
    ['$scope', 'breeze', 'datacontext', 'logger', 
    function HomeController($scope, breeze, datacontext, logger) {
        function initialize(forceRefresh) {
            datacontext.initialize(forceRefresh)
                .then(getSucceeded)
                .fail(queryFailed)
                .fin(refreshView);
        }
        initialize();
        $scope.refresh = refresh;
        function refresh() {
            initialize(true);
        }
        function getSucceeded() {
            $scope.lookups = datacontext.lookups;
            $scope.datasetOne = datacontext.datasetOne;
            $scope.datasetTwo = datacontext.datasetTwo;
        }
        function refreshView() {
            $scope.$apply();
        }
        function queryFailed(error) {
            logger.error(error);
        }       
    }]);

DATACONTEXT:

app.factory('datacontext',
    ['breeze', 'Q', 'logger', 'model',
    function (breeze, q, logger, model) {
        var initialized;
        var manager = configureBreezeManager();
        var datacontext = {
            initialize: initialize,
            metadataStore: manager.metadataStore,
            saveEntity: saveEntity
        };
        return datacontext;
        //#region private members
        function initialize(forceRefresh) {
            if (!initialized || forceRefresh) {
                return primeData(forceRefresh).then(function () {
                    logger.log("Running Initialize");
                });
            } else {
                logger.log("Already Initialized");
                return q();
            }
        }
        function primeData(forceRefresh) {
            return (getLookups(forceRefresh)
                .then(success))
                .then(model.initialize(datacontext))
                .then(getDatasetOne())
                .then(getDataSetTwo())
                .then(getNonDependantDataset);
            function success(data) {
                if (!initialized) {
                    datacontext.lookups = data.results[0];
                    initialized = true;
                } else {
                    datacontext.lookups = {
                        teams: getLocal('Teams', 'id'),
                        // other lookup values here                       
                    };
                }
                // should I call model.initialize(datacontext) here??
            }
        }
        function getLookups(forceRefresh) {
            var query = breeze.EntityQuery
                .from('Lookups');
            if (initialized && !forceRefresh) {
                return true;
            }
            return manager.executeQuery(query);
        }
        function getDatasetOne() {
            var query = breeze.EntityQuery
                .from("EntityNameOne");
            return manager.executeQuery(query).then(getSucceeded);
            function getSucceeded(data) {
                datacontext.datasetOne = model.process(data.results)
                return q();
            }
        }
        function getDatasetTwo() {
            var query = breeze.EntityQuery
                .from("EntityNameTwo");
            return manager.executeQuery(query).then(getSucceeded);
            function getSucceeded(data) {
                datacontext.datasetTwo = model.process(data.results);
                return q();
            }
        }
        function getNonDependentDataset() {
            var query = breeze.EntityQuery
                .from('EntityNameThree');
            return manager.executeQuery(query).then(success);
            function success(data) {
                datacontext.nonNependentDataset = data.results;
            }
        }
        function saveEntity(masterEntity, message) {
            // standard implementation
        }
        function getLocal(resource, ordering) {
            var query = breeze.EntityQuery.from(resource)
                .orderBy(ordering);
            return manager.executeQueryLocally(query);
        }
        function configureBreezeManager() {
            // standard implementation
        }
    }]);

模型:

app.factory('model', ['logger', function (logger) {
    var datacontext;
    extendDatasetOne();
    extendDatasetTwo();
    var model = {
        initialize: initialize,
        getDatasetOne: getDatasetOne,
        getDatasetTwo: getDatasetTwo
    };
    return model;
    function initialize(context) {
        datacontext = context;        
    }
    function getDatasetOne(input) {
        var ret = [];
        for (var i = 0; i < input.length; i++) {
            var item = new TypeOne(input[i]);
            ret.push(item);
        }
        return ret;
    }
    function getDatasetTwo(input) {
        var ret = [];
        for (var i = 0; i < input.length; i++) {
            var item = new TypeTwo(input[i]);
            ret.push(item);
        }
        return ret;
    }
    function TypeOne(item) {
        var self = this;
        for (var prop in item) {
            if (item.hasOwnProperty(prop)) {
                self[prop] = item[prop];
            }
        }
        self.name = getNameForId(item.id);
    }
    function TypeTwo(item) {
        var self = this;
        for (var prop in item) {
            if (item.hasOwnProperty(prop)) {
                self[prop] = item[prop];
            }
        }
        self.name = getNameForId(item.id);
    }
    function extendDatasetOne() {
        // add properties to prototype
    }
    function extendDatasetOne() {
        // add properties to prototype
    }
    function getNameForId(id) {
        var set = datacontext.lookups.items;
        for (var i = 0; i < set.length; i++) {
            if (id == set[i].id) {
                return set[i].name;
            }
        }
        return null;
    }

}]);

创建一个返回promise的函数很简单:

function test() {
    var defer = Q.defer();
    // an example of an async call
    serverCall(function (request) {
        if (request.status === 200) {
            defer.resolve(request.responseText);
        } else {
            defer.reject(new Error("Status code was " + request.status));
        }
    });
    return defer.promise;
}

现在你可以和。then()一起使用了。

下面是一个如何使用primeData函数的例子:

function primeData(forceRefresh) {
    function success(data) {
       if (!initialized) {
         datacontext.lookups = data.results[0];
         initialized = true;
       } else {
         datacontext.lookups = {
           teams: getLocal('Teams', 'id'),
           // other lookup values here                       
          };
       }
    }
    var getLookupsPromise = getLookups(forceRefresh);
    // .then method returns a new promise.
    var successPromise = getLookupsPromise.then(success); 
    // success is called when the getLookupsPromise promise is resolved
    // Now success promise will resove when succes code is resoved.
    // If success where assync and it returned an other promise this will resolve when the promise resolves.
    var modelInitializePromise = getLookupsPromise.then(function () {
        model.initialize(datacontext); 
    });
    var datasetOnePromise = modelInitializePromise.then(getDatasetOne);
    var datasetTwoPromise = modelInitializePromise.then(getDatasetTwo);
    var nonDependantPromise = getNonDependantDataset();
    // Generate a promise that will resolve when all promises are resolved
    return q.all([getLookupsPromise, successPromise, modelInitializePromise, 
        datasetOnePromise, datasetTwoPromise, nonDependantPromise]);
}

相关内容

  • 没有找到相关文章

最新更新