I've spent last few hours trying to make it work but it just doesn't for no apparent reason. I have all the required packages and settings. I get no errors, async
and await
just doesn't wait.
I use Webpack to require the polyfill files that Babel adds, eg babel-runtime/regenerator
.
async function getData() {
let data = await ajaxCall();
console.log(data);
}
function ajaxCall() {
let url = 'https://maps.googleapis.com/maps/api/geocode/json?address=london';
let xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if(xmlhttp.status == 200) {
console.log(JSON.parse(xmlhttp.response));
return JSON.parse(xmlhttp.response);
}
}
}
xmlhttp.open('GET', url, true);
xmlhttp.send();
}
getData();
// It logs "undefined" and then ajax response AFTER
{
"presets": ["es2015", "stage-0"],
"plugins": ["transform-runtime"]
}
Does anyone have any idea what could be wrong?
In order for async
and await
to work you need to return something from your await
ed call that the JS runtime can use to know when to continue the function that is await
ing the result. The "type" that is required for async
/ await
interop is called Promise
.
Your ajaxCall
returns undefined
, which doesn't tell the JS runtime anything, so it doesn't await
because there is nothing to wait for. If you want to make this work, simply return a Promise
from ajaxCall
and resolve it when your ajax request is fulfilled.
At the simplest:
function ajaxCall() {
let url = 'https://maps.googleapis.com/maps/api/geocode/json?address=london';
// The new `window.fetch` API returns a promise for you
return fetch(url).then(response => response.json());
}
or using XMLHttpRequest
:
function ajaxCall() {
let url = 'https://maps.googleapis.com/maps/api/geocode/json?address=london';
return new Promise((resolve, reject) => {
let xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = () => {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 200) {
// resolve instead of return inside of a Promise closure
resolve(JSON.parse(xmlhttp.response));
} else {
// reject instead of throw
// (will throw the error at the `await` expression.)
reject(Error(`Received status code ${xmlhttp.status}`));
}
}
}
xmlhttp.open('GET', url, true);
xmlhttp.send();
});
}
You need to return a promise from the ajaxCall(). Code should look something like that:
function ajaxCall() {
return new Promise((resolve, reject) => {
let url = 'https://maps.googleapis.com/maps/api/geocode/json?address=london';
let xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if(xmlhttp.status == 200) {
console.log(JSON.parse(xmlhttp.response));
resolve(JSON.parse(xmlhttp.response));
}
}
// handle error: reject(error);
}
xmlhttp.open('GET', url, true);
xmlhttp.send();
})
}
then:
async function getData() {
try {
let data = await ajaxCall();
console.log(data);
} catch (e) {
// do something with error
}
}
Note that I used es6 arrow functions
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.