Javascript BreezeJS-链接查询
假设我们有一个客户对象,它有一个“Foo”集合。我希望我的“getCustomer”函数添加所有它还没有的Foos,然后返回它自己,作为一个承诺 所以我想要一个承诺:找到一个客户,然后将所有缺少的foo添加到此客户,这样当承诺得到解决时,客户就拥有了所有缺少的foo 例如: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 =
// 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.
}
}