Javascript BreezeJS-链接查询

Javascript BreezeJS-链接查询,javascript,breeze,q,Javascript,Breeze,Q,假设我们有一个客户对象,它有一个“Foo”集合。我希望我的“getCustomer”函数添加所有它还没有的Foos,然后返回它自己,作为一个承诺 所以我想要一个承诺:找到一个客户,然后将所有缺少的foo添加到此客户,这样当承诺得到解决时,客户就拥有了所有缺少的foo 例如: // dataservice.js // returns Q.Promise<breeze.QueryResult> function getCustomer(custId) { var query =

假设我们有一个客户对象,它有一个“Foo”集合。我希望我的“getCustomer”函数添加所有它还没有的Foos,然后返回它自己,作为一个承诺

所以我想要一个承诺:找到一个客户,然后将所有缺少的foo添加到此客户,这样当承诺得到解决时,客户就拥有了所有缺少的foo

例如:

// dataservice.js

// returns Q.Promise<breeze.QueryResult>
function getCustomer(custId) {
    var query = breeze.EntityQuery().from("Customers").where("CustomerId", "==", custId);
    return this.em.executeQuery(query);
}

// returns Q.Promise<breeze.QueryResult>
function getFoosNotOnCustomer(customer) {
    var query = breeze.EntityQuery().from("Foo").where("CustomerId", "!=", customer.Id());
    return this.em.executeQuery(query);
}

尽管我无法理解语义,但我会以你的表面价值为例。。。尤其是我无法理解为什么得到所有不属于客户的食物会有帮助

我将只关注“链接”,我将假设您希望调用方在完成后占有选定的客户

顺序链接 在本例中,我们在获得FOO之前等待客户

function getCustomer(custId) {

    var cust;
    var em = this.em;
    var query = breeze.EntityQuery().from("Customers")
                .where("CustomerId", "==", custId);

    // On success calls `gotCustomer` which itself returns a promise
    return em.executeQuery(query)
        .then(gotCustomer)
        .fail(handleFail); // you should handleFail 

    // Called after retrieving the customer.
    // returns a new promise that the original caller will wait for.
    // Defined as a nested success function 
    // so it can have access to the captured `cust` variable 
    function gotCustomer(data) {
       cust = data.results[0];

       if (!cust) {
          return null; // no customer with that id; bail out now
       }
       // got a customer so look for non-customer foos
       // returning another promise so caller will wait
       return breeze.EntityQuery().from("Foos")
              .where("CustomerId", "!=", custId)
              .using(em).execute()
              .then(gotFoos);
    }

    // Now you have both the customer and the other Foos;
    // bring them together and return the customer.
    function gotFoos(data) {
        var foos = data.results;
        // assume `notMyFoos` is an unmapped property that 
        // should hold every Foo that doesn't belong to this Customer
        foos.forEach(function(f) { cust.notMyFoos.push(f); }
        return cust; // return the customer to the caller after Foos arrive.
    }
}
并行异步查询 在您的场景中,您真的不必等待客户查询,就可以获得foo。您从一开始就知道客户和FOO的选择标准。假设您认为customer查询返回customer的可能性很高,那么您可能会并行启动这两个查询,然后在两个查询完成后将数据混合在一起。考虑一下这个问题。

function getCustomer(custId) {
    var em = this.em;

    var custPromise = breeze.EntityQuery().from("Customers")
                      .where("CustomerId", "==", custId)
                      .using(em).execute();

    var fooPromise = breeze.EntityQuery().from("Foos")
                      .where("CustomerId", "!=", custId)
                      .using(em).execute();

    Q.all([custPromise, fooPromise])
      .then(success)
      .fail(handleFail); // you should handleFail

    // Now you have both the customer and the "other" Foos;
    // bring them together and return the customer.
    // `data` is an array of the results from each promise in the order requested.
    function success(data) {
        var cust = data[0].results[0];
        if (!cust) return null;

        var foos = data[1].results;

        // assume `notMyFoos` is an unmapped property that 
        // should hold every Foo that doesn't belong to this Customer
        foos.forEach(function(f) { cust.notMyFoos.push(f); }
        return cust; // return the customer to the caller after Foos arrive.
    }
}

请注意,我不必在成功路径中执行太多空检查。当调用成功回调时,我保证有
data.results
。我必须考虑到
custId

没有
Customer
的可能性,我不明白您想做什么。我可以帮你把问题连成一个链。。。所以第二个查询依赖于第一个。。。如果这是你想要的。但您的示例让我感到困惑,因为正如前面所写的,您在开始时知道这两个查询的CustomerId。您可以并行发布这些命令,然后在两者完成后继续。但我感觉我错过了什么。而且我也不知道“所有缺少的食物”是什么意思。您的第二个查询似乎请求数据库中不属于目标客户的所有FOO。你真的是这个意思吗?沃德,是的。我想加载客户实体。然后我想找到客户实例没有的所有foo,并将它们推送到客户实例集合中。返回的内容是我感到困惑的地方,代码变得不可读。我将用一个更好的例子来更新这个问题。如果您询问ID=1的客户,并且有属于ID=2的客户的FOO,该怎么办。这个逻辑将把所有的foo都转移到Customer#2,并将它们转移到Customer#1。这真的是你想要的吗?请注意,您的第一个查询不会检索已经属于Customer#1的FOO。因此,在您请求的操作结束时,缓存中的Customer1.Foos将不返回过去属于Customer#1的foo,也不返回过去属于任何其他客户的所有foo。我不明白。没问题,我试着把我的例子太抽象了。我想我已经明白了——我需要的是延迟。谢谢你的帮助;我将结束这个问题?我不知道我需要它来处理任何听起来像你的案子。看到我的答案了吗?我想我很难找到顺序解决方案,因为我试图在没有cust变量的情况下实现它,而cust变量可以用于这两个函数。但谁在乎呢,您的并行解决方案要好得多!也许更好。它的缺陷是,即使没有具有给定custId的客户,它也会得到Foos。这就是为什么我添加了关于customer查询返回customer的高概率的注释。您的UI可能会使这种可能性非常高(例如,从列表中选择),在这种情况下,并行性可能对您的应用程序有好处。然而,当谈到性能时,我不作任何假设。如此多的理论论点最终证明是错误的。测试和验证。玩得高兴
function getCustomer(custId) {

    var cust;
    var em = this.em;
    var query = breeze.EntityQuery().from("Customers")
                .where("CustomerId", "==", custId);

    // On success calls `gotCustomer` which itself returns a promise
    return em.executeQuery(query)
        .then(gotCustomer)
        .fail(handleFail); // you should handleFail 

    // Called after retrieving the customer.
    // returns a new promise that the original caller will wait for.
    // Defined as a nested success function 
    // so it can have access to the captured `cust` variable 
    function gotCustomer(data) {
       cust = data.results[0];

       if (!cust) {
          return null; // no customer with that id; bail out now
       }
       // got a customer so look for non-customer foos
       // returning another promise so caller will wait
       return breeze.EntityQuery().from("Foos")
              .where("CustomerId", "!=", custId)
              .using(em).execute()
              .then(gotFoos);
    }

    // Now you have both the customer and the other Foos;
    // bring them together and return the customer.
    function gotFoos(data) {
        var foos = data.results;
        // assume `notMyFoos` is an unmapped property that 
        // should hold every Foo that doesn't belong to this Customer
        foos.forEach(function(f) { cust.notMyFoos.push(f); }
        return cust; // return the customer to the caller after Foos arrive.
    }
}
function getCustomer(custId) {
    var em = this.em;

    var custPromise = breeze.EntityQuery().from("Customers")
                      .where("CustomerId", "==", custId)
                      .using(em).execute();

    var fooPromise = breeze.EntityQuery().from("Foos")
                      .where("CustomerId", "!=", custId)
                      .using(em).execute();

    Q.all([custPromise, fooPromise])
      .then(success)
      .fail(handleFail); // you should handleFail

    // Now you have both the customer and the "other" Foos;
    // bring them together and return the customer.
    // `data` is an array of the results from each promise in the order requested.
    function success(data) {
        var cust = data[0].results[0];
        if (!cust) return null;

        var foos = data[1].results;

        // assume `notMyFoos` is an unmapped property that 
        // should hold every Foo that doesn't belong to this Customer
        foos.forEach(function(f) { cust.notMyFoos.push(f); }
        return cust; // return the customer to the caller after Foos arrive.
    }
}