执行3个异步操作(第二个操作取决于条件)

时间:2013-04-16 19:50:10

标签: breeze durandal

我正在开展 durandal / breeze 项目。

我需要在激活功能中执行几项操作。感谢promises我能够链接异步操作。请注意,我仍然是所有这些东西的初学者,所以不要犹豫,纠正我的代码。

我在viewModel中有以下激活功能:

var activate = function (routeData) {

    initLookups()

    var idTran = parseInt(routeData.idTran);
    var idItin = parseInt(routeData.idItin);

    return datacontext.getTransportById(idTran, transport)
            .then(function () { return datacontext.getItineraryById(idItin, itinerary); });
}

所以在return语句中:

  1. 我填写了transport观察者,感谢getTransportById

  2. 然后我填写了itinerary观察者,感谢getItineraryById

  3. -

    到目前为止一切顺利。此代码可以按预期工作并完成其工作(可能未进行优化)。现在我需要在创建新实体的情况下在这两个操作之间插入一个条件(如果idItin == - 1)。在这种情况下,将创建一个新实体。我尝试使用下面的代码,但它不起作用:我的意思是promise似乎没有在这里完成他的工作,因此显示视图而不等待异步操作完成。

    var activate = function (routeData) {
    
        initLookups()
    
        var idTran = parseInt(routeData.idTran);
        var idItin = parseInt(routeData.idItin);
    
        return datacontext.getTransportById(idTran, transport)
                .then(function () { if (idItin == -1) return datacontext.createItineraryDetailTransport(idTran); })
                .then(function () { return datacontext.getItineraryById(idItin, itinerary); });
    }
    

    以下是datacontext的createItineraryDetailTransport函数:

    var createItineraryDetailTransport = function (idTransport) {
    
        var initialValues = ({
            transportId: idTransport
        });
    
        var newItinerary = manager.createEntity(entityNames.itinerary, initialValues);
        return manager.addEntity(newItinerary);
    }
    

    那么有人知道如何编码这个东西吗?

1 个答案:

答案 0 :(得分:0)

我认为严格的方法是:

return datacontext.getTransportById(idTran, transport).then(function () {
    return datacontext.getItineraryById(idItin, itinerary).then(function(){
        if (idItin == -1) return datacontext.createItineraryDetailTransport(idTran);
        //You have to return something different tu null,false,undefined... or a promise
        return true; 
    );
});

此外,如果不需要执行此调用,则可以使用Q库(https://github.com/kriskowal/q)并行执行。解决方案可能是:

if(idItin ==-1){
    //CreateItineraryDetailTransport don't return a promise.
    //You can call that like a normal methond.
    //It is not a asyncronous methond
    datacontext.createItineraryDetailTransport(idTran);
}
return Q.all([datacontext.getTransportById(idTran, transport),datacontext.getItineraryById(idItin, itinerary)]);

- - - - - - - - 编辑

在另外两个调用之间创建解决方案:

   return datacontext.getTransportById(idTran, transport).then(function () {
        if (idItin == -1) return datacontext.createItineraryDetailTransport(idTran).then(function(){
            return datacontext.getItineraryById(idItin, itinerary);
        });
        return datacontext.getItineraryById(idItin, itinerary)
    });

   // I am using Q to do this method return a promise
    var createItineraryDetailTransport = function (idTransport) {

        var deferred = Q.defer();

        var initialValues = ({
            transportId: idTransport
        });

        var newItinerary = manager.createEntity(entityNames.itinerary, initialValues);
        manager.addEntity(newItinerary);

        deferred.resolve(true);
        return deferred.promise;
    }

您也可以使用Q.fcall:

return Q.fcall(function(){ datacontext.createItineraryDetailTransport(idTran);};

我想也许,你不需要做createItineraryDetailTransport返回一个promise。也许这个解决方案也是可能的:

return datacontext.getTransportById(idTran, transport).then(function () {
    if (idItin == -1) datacontext.createItineraryDetailTransport(idTran);
    return datacontext.getItineraryById(idItin, itinerary);
});