0

我用 Durandal/Breeze/Knockout 开发了一个应用程序。

在我的 javascript 中,我想一个接一个地执行 2 个异步操作。

  • 首先是收集我所有的“警报”,其中 transportId 通过参数传递,类别为“全局”

  • 第二个是删除上面收集的所有这些实体

这是我到目前为止所做的:

var checkAlarmsOnTransport = function (id) {

    var alarms = ko.observableArray();
    getAlarms(alarms, id, 'Global')
        .then(deleteAlarms(alarms));
};

var getAlarms = function (alarmsObservable, transportId, category, forceRemote) {
    // Input: transportId
    // Input: category
    // Input: forceRemote: boolean to force the fetch from server
    // Output: alarmsObservable: an observable filled with all the alarms

    if (forceRemote)
        queryCacheAlarms = {};

    var p1 = new Predicate('transportId', '==', transportId);
    var p2 = new Predicate('category', '==', category);
    var query = entityQuery.from('Alarms')
                           .orderBy('id')
                           .where(p1.and(p2));

    var isInCache = (queryCacheAlarms === true);

    if (isInCache && !forceRemote) {
        query = query.using(breeze.FetchStrategy.FromLocalCache);
    } else {
        queryCacheAlarms = true;
        query = query.using(breeze.FetchStrategy.FromServer);
    }

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

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

    function querySucceeded(data) {
        console.log("the get return:" + data.results.length); // <---------- added
        alarmsObservable(data.results);
    }
};

var deleteAlarms = function (alarmsObservable) {
    // Input: alarmsObservable: an observable filled with a list of alarms to delete
    // Output: none
    console.log("deleted:" + alarmsObservable().length); // <------------- added
    for (var i = alarmsObservable().length - 1; i >= 0 ; i--) {
        alarmsObservable()[i].entityAspect.setDeleted();
    };
};

我成功地独立成功地测试了这两个功能。现在我想异步使用它,但它不起作用。

任何想法?

感谢任何人指出我正确的方向。


更新

我像 CodeThug 建议的那样更新了我的代码,然后我console.log在我的 2 个函数中添加了 2 行来跟踪所做的事情。看上面。

控制台显示:

  • 已删除:0

  • 得到回报:6

因此,似乎该deleteAlarms函数在 the 之前被调用getAlarms,因此deleteAlarms收到了 0 个元素的输入。

知道为什么电话被颠倒了吗?

4

2 回答 2

1

getAlarms方法返回如下:

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

getAlarms这样打电话:

getAlarms(alarms, id, 'Global')
    .then(deleteAlarms(alarms));

所以你正在有效地尝试这样做:

manager.executeQuery(query)
    .then(querySucceeded)
    .fail(queryFailed)
    .then(deleteAlarms(alarms));

但是,您不能在 a.then()之后链接 a .fail().then()并且.fail()是可以在 Promise 上调用的方法。 .then()返回一个承诺,您可以通过这种方式链接调用:

myPromise.then(...).then(...).then(...)

你可以有一个.fail()after a .then(),因为.then()返回一个承诺:

myPromise.then(...).fail(...);

但是,.fail()返回未定义,并且您不能调用.then()未定义。所以这行不通

// This won't work (this is what you're trying to do)
myPromise.then(...).fail(...).then(...);

试试这个:

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

然后你可以保持getAlarms原样调用:

getAlarms(alarms, id, 'Global')
    .then(deleteAlarms(alarms));
于 2013-05-03T15:01:45.567 回答
0

我认为问题可能在本节中:

var alarms = ko.observableArray();
getAlarms(alarms, id, 'Global')
  .then(deleteAlarms(alarms));

你必须这样做:

var alarms = ko.observableArray();
getAlarms(alarms, id, 'Global')
  .then(function(){deleteAlarms(alarms);});

因为你需要传递一个函数给then。

我希望这能帮到您。

于 2013-05-03T14:55:17.500 回答