0

我对 JS 有点陌生,我正在尝试考虑在我正在处理的应用程序中设计一些异步交互的最佳方法。

我有一个与一些 API 支持的实时数据相关的记录列表。我向用户显示这些记录的列表,用户可以选择他们想要查看更多信息的特定记录。我通过 ajax 调用从 API 加载这些附加数据。

为了使这成为一个更真实的例子,假设我拥有的是一个股票列表。我知道每只股票的名称和昨天的收盘价。每个股票名称旁边都有一个复选框,如果用户选中此框,它会在图表上绘制过去一年的股票历史价格。

当用户在途中选择一只股票时,行为很简单。我针对一只股票的历史数据发送了一个 API 请求,并将其绘制在图表上。

但是,用户可能会一次选择一堆股票,或者快速连续地选择。我不想连续发出 10 或 20 或 50 个请求,我想发出 10 或 20 或 50 个股票历史的请求。

假设我的应用程序有一个事件监听器,当复选框被切换时,它会查找股票历史记录,如下所示:

$('input.stock_toggle').change( function(event){
  var symbol = $(this).data('symbol');
  lookupStockHistory(symbol);
});

我如何定义一个lookupStockHistory函数或其他类型的事件侦听器等,它会等待一秒钟并汇集所有传入的事件以发送单个请求而不是连续触发多次?

4

3 回答 3

2
var lookupStockHistory = (function () {
"use strict";
var qeue = [], timeoutHandler = null, timeoutTime = 1000,
    sendCall = function () {
        //process qeue array and trigger ajax call
        //and clean qeue
        qeue = [];
    },
    add = function (symbol) {
        if (timeoutHandler) {
            clearTimeout(timeoutHandler);
            timeoutHandler = null;
        }
        qeue.push(symbol);
        timeoutHandler = setTimeout(sendCall, timeoutTime);
    };
return add;}());

要触发只需调用lookupStockHistory(symbol). 这会将符号收集到数组,该数组将在自上次调用后 1 秒后处理

于 2013-05-14T17:02:30.473 回答
1

您可以使用您的命名空间将您的请求推送到“全局变量”中,然后用于setTimeout延迟 AJAX 调用(可能是一两秒?)。

setTimeout调用一个从“全局变量”获取请求的函数,清空变量,然后构造您的请求。对该函数的任何后续调用setTimeout都会看到“全局变量”为空,并且不会构造未来的 AJAX 请求。

在下面的示例中,我还删除了当前挂起的超时,因为已经启动了一个新的超时。

这是一个使用 jQuery 进行选择和事件捕获的伪代码示例:

var DELAY_FOR_INPUT = 2000; // 2 seconds

var g_MyDataToRequest = [];
var g_currentAJAXCallTimeout = null;

function _callAPI = new function() {
   g_currentAJAXCallTimeout = null;
   var dataToGet = g_MyDataToRequest;
   g_MyDataToRequest = []; // clear out global request cache

   // TODO: Loop over dataToGet and construct AJAX request
   // TODO: Perform AJAX call...
}

$('.myCheckbox').click(function() {
   var myRequest = $(this).attr("ID"); // or Val(), or whatever you'd like to track your item
   g_MyDataToRequest.push( myRequest );

   // If have a pending request, kill it
   if (g_currentAJAXCallTimeout != null) {
     clearTimeout(g_currentAJAXCallTimeout);
     g_currentAJAXCallTimeout = null;
   }

   g_currentAJAXCallTimeout = setTimeout( _callAPI, DELAY_FOR_INPUT );
});

如前所述,这是伪代码,可能无法正常工作,但它应该能让你继续前进。

于 2013-05-14T17:09:37.933 回答
0

您可以实现一个计时器并通过第一次单击或更改事件启动它。每次额外的点击或更改事件,您都可以重置计时器。此外,对于每个事件,您都可以相应地将符号值添加或删除到数组中。计时器到期后,您将数组加入为逗号分隔的字符串,并通过 ajax 将其发回并获得 JSON 结果。

于 2013-05-14T17:02:49.667 回答