admin管理员组文章数量:1316974
I am attempting to get a public IP address from an API and then having that IP to be used inside another function (ninjaUniqueVisitorRequest()
).
I have the following code:
function ninjaGetIp() {
var ipRequest = new XMLHttpRequest();
ipRequest.open('GET', "=", true);
ipRequest.send();
ipRequest.onload = function () {
if (ipRequest.status >= 200 && ipRequest.status < 400) { // If response is all good...
return ipRequest.responseText;
} else {
console.log('There was an error retrieving the public IP.');
return '127.0.0.1';
}
}
}
async function ninjaUniqueVisitorRequest() {
// var ninjaSiteUuid = ninjaGetSiteUuid();
// var ninjaFingerprint = await ninjaGetFingerprint();
var ninjaPublicIp = await ninjaGetIp();
console.log(ninjaPublicIp);
}
Currently, when I run ninjaUniqueVisitorRequest();
the console.log(ninjaPublicIp);
returns undefined
.
I kind of understand that it returns straight away before the request has been made however thats what I thought I was fixing by using async/await
.
Any ideas are appreciated! PHP guy over here, go easy on me.
I am attempting to get a public IP address from an API and then having that IP to be used inside another function (ninjaUniqueVisitorRequest()
).
I have the following code:
function ninjaGetIp() {
var ipRequest = new XMLHttpRequest();
ipRequest.open('GET', "https://api.ipify?format=jsonp=", true);
ipRequest.send();
ipRequest.onload = function () {
if (ipRequest.status >= 200 && ipRequest.status < 400) { // If response is all good...
return ipRequest.responseText;
} else {
console.log('There was an error retrieving the public IP.');
return '127.0.0.1';
}
}
}
async function ninjaUniqueVisitorRequest() {
// var ninjaSiteUuid = ninjaGetSiteUuid();
// var ninjaFingerprint = await ninjaGetFingerprint();
var ninjaPublicIp = await ninjaGetIp();
console.log(ninjaPublicIp);
}
Currently, when I run ninjaUniqueVisitorRequest();
the console.log(ninjaPublicIp);
returns undefined
.
I kind of understand that it returns straight away before the request has been made however thats what I thought I was fixing by using async/await
.
Any ideas are appreciated! PHP guy over here, go easy on me.
Share Improve this question asked Jan 25, 2019 at 0:24 KriiVKriiV 2,0204 gold badges27 silver badges45 bronze badges 6-
6
Your
ninjaGetIp()
function is notasync
and does not return a Promise. – Pointy Commented Jan 25, 2019 at 0:26 -
I thought you simply put
async
on the function you're calling from. Also from my understandingreturn xyz
will be converted to a promise anyway? I'm piling with Babel. – KriiV Commented Jan 25, 2019 at 0:27 - If you want promised based AJAX use the fetch() API. – Randy Casburn Commented Jan 25, 2019 at 0:28
-
@KriiV it would be converted to a promise if you had any
return
there and if you marked it withasync
.ninjaGetIp
returns nothing. – zerkms Commented Jan 25, 2019 at 0:28 - Possible duplicate of How do I return the response from an asynchronous call? – Jared Smith Commented Jan 25, 2019 at 0:44
2 Answers
Reset to default 6Currently your ninjaGetIp
is not an awaitable Promise
.
You can try just returning a new Promise
that wraps the implementation or just add async
keyword before the function.
function ninjaGetIp() {
return new Promise(function (resolve, reject) {
var ipRequest = new XMLHttpRequest();
ipRequest.open('GET', "https://api.ipify?format=jsonp=", true);
ipRequest.send();
ipRequest.onload = function () {
if (ipRequest.status >= 200 && ipRequest.status < 400) { // If response is all good...
return resolve(ipRequest.responseText);
} else {
console.log('There was an error retrieving the public IP.');
return resolve('127.0.0.1');
}
}
});
}
Async sample
async function ninjaGetIp() {
var ipRequest = new XMLHttpRequest();
ipRequest.open('GET', "https://api.ipify?format=jsonp=", true);
ipRequest.send();
ipRequest.onload = function () {
if (ipRequest.status >= 200 && ipRequest.status < 400) { // If response is all good...
return ipRequest.responseText;
} else {
console.log('There was an error retrieving the public IP.');
return '127.0.0.1';
}
}
}
That's because ninjaGetIp
is not awaitable. You have to return a Promise
in order to be able to await
.
async function ninjaGetIp() {
return new Promise( (resolve, reject) => {
var ipRequest = new XMLHttpRequest();
ipRequest.open('GET', "https://api.ipify?format=jsonp=", true);
ipRequest.send();
ipRequest.onload = () => {
if (ipRequest.status >= 200 && ipRequest.status < 400) { // If response is all good...
resolve(ipRequest.responseText);
} else {
console.log('There was an error retrieving the public IP.');
reject('127.0.0.1');
}
}
});
}
Also, you can simplify it and use fetch
which returns a promise instead of using all the code required to build up an XMLHttpRequest
:
async function ninjaGetIp() {
return fetch('https://api.ipify?format=jsonp=');
}
TL;DR;
If you want to stick with XMLHttpRequest
, I would create a wrapper for it because it's a lot of redundant code: Here's an example:
class HttpClient {
constructor(){}
async get(url) {
return new Promise( (resolve, reject) => {
const xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = (evt) => {
if (evt.currentTarget.readyState === 4 && evt.currentTarget.status === 200) {
try {
const response = JSON.parse(evt.currentTarget.response);
resolve(response);
} catch (exception) {
reject(exception);
}
}
};
xhttp.open('GET', url, true);
xhttp.send();
});
}
async post(url, data) {
return new Promise( (resolve, reject) => {
const xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = (evt) => {
if (evt.currentTarget.readyState === 4 && evt.currentTarget.status === 200) {
try {
const response = JSON.parse(evt.currentTarget.response);
resolve(response);
} catch (exception) {
reject(exception);
}
}
};
xhttp.open('POST', url, true);
xhttp.send(data);
});
}
}
Usage
const httpClient = new HttpClient();
const data = await httpClient.get('some url');
- Fetch API
- Async
- Await
本文标签: javascriptAsyncAwaitreturned variable is undefined after XHR requestStack Overflow
版权声明:本文标题:javascript - AsyncAwait, returned variable is undefined after XHR request - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742019661a2414428.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论