hyde hyde - 6 months ago 41
Ajax Question

Functional promise using jQuery

I am trying to download some data from a Phoenix web app and render the data on the front-end. For this I have the request and callback in a list and am running a list.reduce against it while

ing each request.

var Database = function() {
this.reservations = [];
this.applications = [];
this.environments = [];

var database = new Database();

var requests = [$.getJSON('/api/applications', data => { database.applications = data }),
$.getJSON('/api/environments', data => { database.environments = data }),
$.getJSON('/api/reservations', data => { database.reservations = data })];

function run() {
requests.reduce(function(chain, callback) {
return (chain ? chain.then(callback) : callback);
}, null).then(() => render(database));

However, this works most of the time in latest version of Google Chrome and maybe 10% of the times in Safari.

When I inspect the "database" after stepping into the render function, I see list of applications, but not environments and reservations (2 pieces of data).

Edit: Okay, so it works in Google Chrome in normal mode. But does not work all the time in incognito mode. In Safari it sometimes fetches all 3 pieces of data, and sometimes just 2 pieces of data. My application does not use any sessions.

I am guessing this is caused by the nature of $.ajax being asynchronous and perhaps I broke my promises. But I have hit a roadblock.

Any insights?


You don't need to chain your promises, they can all be requested at the same time since it doesn't look like any of them rely on each other. Instead, you can use a .map() and take the result, which will be a list of promises, and use an .all() to wait for them all to resolve.

(I'm taking some liberties so the following should be considered pseudo-code)

var urls = ['whatever.com', 'example.com/something', 'something.com/whatever'];

var requestPromises = urls.map(function(url) {
    return ajax(url); // assume ajax() returns a promise

Promise.all(requestPromises).then(function(results) {