在微风preserving异步查询订单/角 [英] Preserving asynchronous query order in Breeze/Angular

查看:116
本文介绍了在微风preserving异步查询订单/角的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用BreezeJS来处理NG网的服务器端筛选。要做到这一点,我只是 $看荷兰国际集团为改变NG-电网滤波器,并与BreezeJS刷新我的数据。如果我输入速度不够快,虽然,AJAX查询最终会回来坏了。

I'm using BreezeJS to handle server-side filtering of an ng-grid. To do this, I'm just $watch'ing for changes to the ng-grid filter, and refreshing my data with BreezeJS. If I type fast enough though, the AJAX queries can end up coming back out of order.

我在想,每个查询(通过关闭)赛道的最后一个查询请求的GUID有人指出,关联一个GUID,守信。然后忽略了返回不匹配的GUID(我不需要过时的查询结果 - 仅仅是最近的)任何问题。

I was thinking about associating a GUID with each query (via closure), and keeping track of the GUID of the last query request that was made. Then ignoring any queries that returned that didn't match that GUID (I don't need outdated query results - just the most recent).

但是,有处理这一点,特别是在角/微风更好,或更地道的方式?

But is there was a better, or more idiomatic way of handling this, particularly in Angular/Breeze?

推荐答案

@Adam是为您的主要问题的一个重要的想法...驯服,你发射了查询的乱舞当用户键入搜索框

@Adam is on to an important idea for your primary problem ... taming the flurry of queries that you're firing off as users type in the search box.

您应该反跳(又名节流)开始取消请求之前的搜索条目。这意味着等待用户​​停止键入您发出查询到服务器。

You should "debounce" (AKA, "throttle") the search entry before you start canceling requests. That means waiting for the user to stop typing before you issue a query to the server.

在网络中搜索角和反跳,你会发现一些技巧。我使用的是绑定在搜索框中 ngChanged = vm.searchChanged()。该视图模型的 searchChanged 方法,然后将启动 $超时。如果用户输入任何东西在1/2第二,我取消暂停和开始另一个。沉默500毫秒后,我会开始查询。我也想立即开始模糊,或者如果他们按Enter键。

Search the web for "Angular" and "Debounce" and you'll discover a number of techniques. One I used was to bind the search box to ngChanged=vm.searchChanged(). The ViewModel's searchChanged method would then start a $timeout. If the user entered anything within 1/2 a second, I'd cancel that timeout and start another. After 500ms of silence I'd start a query. I'd also start immediately on blur or if they hit the enter key.

当角V.1.3被释放(很快了),反跳将是角结合部。我期待着捣毁我自制去抖code。

When Angular v.1.3 is released (very soon now), "debounce" will be part of Angular binding. I'm looking forward to trashing my homebrew debounce code.

想象一下,用户停止输入500毫秒,查询开始,...和不耐烦的用户想取消该请求。她不能这样做,在微风v.1.4.11。她将能够在v.1.4.12

Imagine the user stops typing for 500ms, the query starts, ... and the impatient user wants to cancel the request. She can't do that in Breeze v.1.4.11. She will be able to in v.1.4.12.

我只是延长了微风AJAX适配器jQuery和角度,以促进双方的响应,并取消超时<一个href="http://stackoverflow.com/questions/23438398/is-it-possible-to-cancel-breeze-requests-angularjs">another对你的问题的。

I just extended the Breeze AJAX adapters for jQuery and Angular to facilitate both cancel and timeout in response to another question of yours.

有在其中启动多个请求的其他情形。响应不一定会到达您的请求的顺序。这是异步的性质

There are other situations in which you launch multiple requests. The responses won't necessarily arrive in the order of your requests. That's the nature of async.

您绝对可以保持这个顺序直自己。请记住,您构造的回调。你可以保持您增加为每个查询和保存应用程序范围请求计数器......,然后在回调引用。

You absolutely can keep the order straight yourself. Remember that you construct the callbacks. You can maintain an application-wide request counter that you increment for each Query and Save ... and then reference in your callbacks.

我在<一个写了一个说明性的例子href="https://github.com/Breeze/breeze.js.samples/blob/master/net/Doc$c$c/Doc$c$c/tests/queryTests.js"相对=nofollow> 文档code:queryTests.js 的显示做到这一点的一种方法:

I wrote an illustrative example in DocCode:queryTests.js that shows one way to do it:

/*********************************************************
* Dealing with response order
* It's difficult to make the server flip the response order
* (run it enough times and the response order will flip)
* but the logic of this test manifestly deals with it
* because of the way it assigns results.
*********************************************************/
asyncTest("can sequence results that arrive out of order", 3, function() {
    var nextRequestId = 0;
    var em = newEm();
    var promises = [];
    var results = [];
    var arrived = [];

    promises.push(breeze.EntityQuery.from('Customers')
        .where('CompanyName', 'startsWith', 'a')
        .using(em).execute()
        .then(makeSuccessFn()).catch(handleFail));

    promises.push(breeze.EntityQuery.from('Customers')
        .where('CompanyName', 'startsWith', 's')
        .using(em).execute()
        .then(makeSuccessFn()).catch(handleFail));

    function makeSuccessFn() {
        var requestId = nextRequestId++;
        return function success(data) {
            // Don't know which response arrived first?
            // Sure you do. Just refer to the requestId which is a capture
            arrived.push(requestId);
            results[requestId] = data.results;
            assertWhenDone();
        }
    }

    function assertWhenDone() {
        if (results[0] && results[1]) {
            start(); // we're done
            // Here we report the actual response order
            ok(true, "Request #{0} arrived before #{1}".format(arrived[0], arrived[1]));
            // no matter what the response order
            // the 'a' companies go in results slot #0
            // the 's' companies go in results slot #1
            var aCompany = results[0][1].CompanyName();
            var sCompany = results[1][1].CompanyName();
            equal(aCompany[0].toLowerCase(), 'a',
                "company from first batch should be an 'a', was " + aCompany);
            equal(sCompany[0].toLowerCase(), 's',
                "company from second batch should be an 's', was " + sCompany);
        }
    }
});

更新2015年1月21日

我应该提到的是,所有承诺方法传递的响应阵列的则(...)成功回调preserves的请求命令。如果你碰巧发出在同一时间多个查询在同一个地方,可以等待在一起(如上面的例子),你并不需要所有的的requestId <的繁重/ code>。只要做到这一点......

Update 21 Jan 2015

I should have mentioned that the all promises method passes a response array to the then(...) success callback that preserves the request order. If you happen to issue more than one query at the same time in the same place and can await them together (as in the example above), you don't need all of the heavy lifting of the requestId. Just do this ...

var promises = [];

promises.push(breeze.EntityQuery.from('Customers')
        .where('CompanyName', 'startsWith', 'a')
        .using(em).execute();

promises.push(breeze.EntityQuery.from('Customers')
        .where('CompanyName', 'startsWith', 's')
        .using(em).execute();

// Q.all waits until all succeed or one of them fails
// breeze.Q is typically $q in an Angular app
breeze.Q.all(promises).then(allSucceeded).catch(atLeastOneFail);

function allSucceeded(responses) {
   // response[0] is from the first 'a' query regardless of when it finished.
   // response[1] is from the second 's' query regardless of when it finished.      
}

这篇关于在微风preserving异步查询订单/角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆