简体   繁体   中英

Javascript: multiple events, one ajax request

I'm somewhat new to JS and I'm trying to think of the best way to design some asynchronous interaction in an application I'm working on.

I've got a list of records that are related to some live API-backed data. I show the user a list of these records, and the user can select specific records that they want to see more information about. I load this additional data from the API via an ajax call.

To make this a more real world example, let's say what I have is a list of stocks. I've got the name and yesterday's closing price for each stock. There's a check box next to each stock name, and if the user checks this box it plots the historic price of the stock for the past year on a graph.

When the user selects one stock in the way, the behavior is simple. I send one API request for the historical data for one stock, and I plot it on the graph.

However, the user might select a bunch of stocks at once, or in rapid succesion. I don't want to fire 10 or 20 or 50 requests back-to-back, I want to make one request for 10 or 20 or 50 stock histories.

Let's say my application has an event listener that looks up the stock history when the check box is toggled, something like this:

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

How could I define a lookupStockHistory function, or some other kind of event listener etc., that would wait a second and pool all the events that came in to send a single request instead of firing many times in row?

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;}());

To trigger just call lookupStockHistory(symbol) . This will gather symbol to array which will be processed after 1 second since last call

You can use push your request into a "global variable" with your namespace, and then use setTimeout to delay the AJAX call (a second or two maybe?).

The setTimeout would call a function that gets the requests from the "global variable", empties the variable, and then constructs your request. Any subsequent calls to the setTimeout function would see that the "global variable" was empty and not construct future AJAX requests.

In the example below, I also remove the current pending timeout as a new one has been initiated.

Here's a pseudo-code example using jQuery for selection and event capture:

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 );
});

This is, as noted, pseudocode and may not quite work right, but it should get you going.

You could implement a timer and start it with the first click or change event. And with each additional click or change event you can reset the timer. Also, with each event you can add or remove the symbol value to an array accordingly. Once the timer expires, you join the array to be a comma-delimited string and post that back via ajax and get a JSON result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM