Languages
[Edit]
EN

JavaScript - AJAX / fetch requests with multiplexing

6 points
Created by:
Shri
8550

In this short article we would like to show how to write in JavaScript own logic that joins in proper order as single array of results of many requests. Presented solution uses as configuration to know about items distibution in returned list. When it is necessary the logic maked AJAX request to complete needed data.

Example code:

// ONLINE-RUNNER:browser;

function RequestMultiplexer(proportions, request) {
    var capacity = 0;
    var states = [ ];
    var processing = false;
    var instances = { };
    for (var i = 0; i < proportions.length; ++i) {
        var proportion = proportions[i];
        var type = proportion.type;
        var count = proportion.count;
        var instance = instances[type];
        if (instance) {
            instance.limit += count;
        } else {
            instances[type] = {
                offset: 0,
                limit: count,
                storage: [ ]
            };
        }
        capacity += count;
    }
    for (var i = 0; i < proportions.length; ++i) {
        var proportion = proportions[i];
        states.push({
            type: proportion.type,
            limit: proportion.count,
            instance: instances[proportion.type]
        });
    }
    function removeState(type) {
        for (var i = states.length - 1; i > -1; --i) {
            var state = states[i];
            if (state.type == type) {
                states.splice(i, 1);
            }
        }
    }
    this.request = function(callback) {
        if (processing || states.length == 0) {
            return false;
        }
        processing = true;
        var index = 0;
        var state = states[index];
        var share = state.limit;
        var instance = state.instance;
        var storage = instance.storage;
        var result = [ ];
        var change = function() {
            index += 1;
            if (index >= states.length) {
                index = 0;
            }
            state = states[index];
            share = state.limit;
            instance = state.instance;
            storage = instance.storage;
        };
        var repeat = function() {
            setTimeout(iterate);
        };
        var navigate = function() {
            change();
            repeat();
        };
        var complete = function() {
            var count = Math.min(state.limit, storage.length, capacity - result.length);
            if (count > 0) { // page is not completed yet
                var slice = storage.splice(0, count);
                for (var i = 0; i < slice.length; ++i) {
                    result.push(slice[i]);
                }
                if (result.length < capacity) {
                    share -= slice.length;
                    if (share > 0) {
                        return repeat();
                    }
                    return navigate();
                }
            }
            processing = false;
            return callback(result);
        };
        var iterate = function(){
            var count = Math.min(state.limit, capacity - result.length);
            if (count > storage.length) { // data should be fetch by additional request
                var commit = function(data, disable) {
                    if (disable) {
                        remove(state.type);
                    }
                    if (data.length > 0) {
                        instance.offset += data.length;
                        for (var i = 0; i < data.length; ++i) {
                            storage.push({
                                type: state.type,
                                data: data[i]
                            });
                        }
                        complete();
                    } else {
                        navigate();
                    }
                };
                request(state.type, instance.offset, commit);
            } else {
                complete();
            }
        };
        setTimeout(iterate);
        return true;
    };
}

// Example usage:

// We want to mix data following way:
//   message picture picture picture video video
//   message picture picture picture video video
//   message picture picture picture video video
//   etc.

var proportions = [
    { type: 'message', count: 1 },
    { type: 'picture', count: 3 },
    { type: 'video',   count: 2 }
];

var request = function(type, offset, callback) {
    console.log('REQUEST FOR: ' + type + 's');
    //TODO: request with AJAX to proper link type and callback call
    var response = [
        { id: offset + 0, name: 'Item name' },
        { id: offset + 1, name: 'Item name' },
        { id: offset + 2, name: 'Item name' },
        { id: offset + 3, name: 'Item name' },
        { id: offset + 4, name: 'Item name' },
        { id: offset + 5, name: 'Item name' }
    ];
    callback(response);
};

var requester = new RequestMultiplexer(proportions, request );

function execute(counter) {
  	if (counter == 0) {
    	return;
    }
    var callback = function(response) {
        // response contains combined data according to proportions
        for (var i = 0; i < response.length; ++i) {
            var item = response[i];
            console.log('JOINED: ' + item.type + '-' + item.data.id + ' ' + item.data.name);
        }
      	execute(counter - 1);
    };
  	requester.request(callback);
}

execute(3);

Alternative titles

  1. JavaScript - AJAX multiplexer
  2. JavaScript - fetch method multiplexer
  3. JavaScript - mix AJAX results in queue
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join