【问题标题】:Struggling with Q promises in Durandal app在 Durandal 应用程序中与 Q 承诺作斗争
【发布时间】:2013-05-10 17:57:33
【问题描述】:

在我的视图模型的激活方法中,我有以下代码。

function activate() {
    var promise = Q.all([datacontext.getManufacturers(manufacturers)]);
    logger.log('Frames View Activated', null, 'frames', false);
    return promise;
}

在我的数据上下文代码中,我有

var getManufacturers = function (manufacturerObservable) {
    var query = entityQuery.from('Manufacturers')
        .orderBy('name');

    return manager.executeQuery(query)
        .then(querySucceeded)
        .fail(queryFailed);

    function querySucceeded(data) {
         if (manufacturerObservable) {
             manufacturerObservable(data.results);
         }
         log('Retrieved [Manufacturer] from remote data source',
             data, false);
    }
};

我希望设置承诺的方式将检索制造商,然后激活方法将完成。我希望在“框架视图激活”日志消息之前出现“从远程数据源检索 [制造商]”日志消息,但实际上相反。如何在激活方法完成之前完成数据检索?

【问题讨论】:

    标签: breeze durandal q


    【解决方案1】:

    在这种情况下,我认为您根本不需要 Q。微风数据管理器返回自己的承诺。

    function activate() {
        logger.log('Frames View Activated', null, 'frames', false);
        return datacontext.getManufacturers(manufacturers);
    }
    

    这确保在激活函数返回之前getManufacturer函数已经完成。

    但是,如果您希望 Frames View Activated 在检索到的消息之后显示,那么您可以使用 promise.spread.then(function() {logger.log('Frames View Activated', null, 'frames', false); })promise.then(function() {logger.log('Frames View Activated', null, 'frames', false); })

    【讨论】:

    • 即使我做 var promise = Q.all([datacontext.getManufacturers(manufacturers)]).then(logger.log('Frames View Activated', null, 'frames', false)) ;回报承诺;加载的日志消息仍然出现在 getManufacturers 中的日志消息之前。
    • 应该是 .then(function(){logger.log('Frames View Activated', null, 'frames', false);}); // 你应该传递将被称为“then”的函数,而不是调用它。
    • 正如 Pawel 所说,您必须在 .then() 中添加记录器消息。我编辑了答案以供将来参考。
    • 为什么Q.all([datacontext.getManufacturers(manufacturers)])?使用Q.all 等待多个承诺。在这里你只有一个。应该是:datacontext.getManufacturers(manufacturers).then(function(){logger.log('Frames View Activated', null, 'frames', false); });
    【解决方案2】:

    这里的问题似乎是,虽然轻风使用的是 Q 延迟/承诺实现,但 Durandal 使用的是 JQuery 延迟/承诺实现。

    将两者混合使用可能会遇到一些问题。

    如果您阅读 Durandal 文档,他们有一个解决方案可以让 Durandal 使用 Q 而不是 JQuery,以便您为您的应用程序获得一致的延迟/承诺解决方案。

    【讨论】:

    • Jorn,我用 spinet 将默认的 Promises 替换为 Q Promises,这对我很有帮助。
    • system.defer = function (action) { var deferred = Q.defer(); action.call(延期,延期); var promise = deferred.promise; deferred.promise = function () { return promise; };延期退货; };