I'm working with async/await functions in Javascript for the first time. I'm having trouble getting my script to wait for an AJAX response before proceeding and then reading/using that response.
I know there are a lot of questions already on here regarding async/await functions not waiting as intended, but none of the answers to the other questions seemed to work for me.
Basically, what I'm trying to do is loop through an array of layer names (for an OpenLayers
map), and forEach
layer name I'm sending an AJAX call to retrieve a record (if it exists) from a MySQL database. Then I simply display the result, move on to the next layer name, send the next AJAX call, etc.
Here's my code:
async function getCellLayers() {
layerNames = [];
map.getLayers().forEach(function(layer) {
if (layer.get('type') == "cell") {
if (layer.getZIndex() == 100) {
layerNames.push(layer.get('name'));
if (layerNames.length == 1) {
fullExtent = layer.getSource().getExtent();
} else {
ol.extent.extend(fullExtent, layer.getSource().getExtent());
}
}
}
});
return layerNames;
}
async function getRecord(cell_date) {
$.ajax({
url: 'rec/getRecord/'+cell_date,
type: 'get',
dataType: 'json',
success: await function(response){
console.log("getRecord response: "+JSON.stringify(response));
return response['data'];
}
});
}
async function testAsyncAwaitFunction() {
let layerNames = await getCellLayers();
layerNames.forEach(async function(layerName) {
cell_date = layerName.substring(3)+"_"+window['currentImage'].substring(17,25);
console.log(cell_date+":");
let cellRecord = await getRecord(cell_date);
console.log("Matches: "+cellRecord.length);
console.log("testAsyncAwaitFunction response: "+JSON.stringify(cellRecord));
});
}
I'm expecting to see something like this in the console:
cell101_20190202:
getRecord response: {"data": [{"id":1,"record":"cell101_20190202","value":"0.8"}]}
Matches: 1
testAsyncAwaitFunction response: {"data": [{"id":1,"record":"cell101_20190202","value":"0.8"}]}
cell102_20190202:
getRecord response: {"data": [{"id":2,"record":"cell102_20190202","value":"0.7"}]}
Matches: 1
testAsyncAwaitFunction response: {"data": [{"id":2,"record":"cell102_20190202","value":"0.7"}]}
[ ... and so on ... ]
But instead I'm getting this:
cell101_20190202:
cell102_20190202:
(...)
getRecord response: {"data": [{"id":1,"record":"cell101_20190202","value":"0.8"}]}
getRecord response: {"data": [{"id":2,"record":"cell102_20190202","value":"0.7"}]}
(...)
getRecord response: {"data": [{"id":14,"record":"cell202_20190202","value":"0.6"}]}
(200x) Uncaught (in promise) TypeError: Cannot read property 'length' of undefined
getRecord response: {"data": [{"id":15,"record":"cell204_20190202","value":"0.5"}]}
(...)
I never see the JSON.stringify
lines prefixed with testAsyncAwaitFunction response
, presumably because the line before that console.log command, which attempts to get the length of cellRecord, fails as the AJAX response hasn't arrived yet.
I suspect the following line will be the key here:
let cellRecord = await getRecord(cell_date);
but I can't work out why that one doesn't seem to be "awaiting" even though this other line a few lines above seems to be working just fine:
let layerNames = await getCellLayers();
Would really appreciate some help from someone with a better grasp of using async/await. I'm much more accustomed to PHP and Python and am having a hard time changing my mindset to thinking asynchronously.