I'm Trying To Understand How To Use Promises In Javascript, But My Script Never Executes The "Then"
Solution 1:
One way that may help you to think more in promises is that once you're in promise-land you can only get the data while you're still in promise-land. In your example, you're getting the data from the fetch
promise. That means that you can only use that data from inside of the fetch
promise. Notice here:
.then(function(myJson) {
arr.push(myJson);
})
callback(arr);
The arr.push
where you're building the array is inside the promise, but callback(arr)
is outside. Since you're not inside the promise anymore you can't get the data.
In your case you also want to wait on multiple promises simultaneously since you're fetching data from multiple sources at once. The best way to do this would be to use Promise.all
and an array of promises:
const promise = Promise.all(users.map(user => {
const url = `https://api.twitch.tv/helix/users?login=${user}`;
return fetch(url, { headers })
.then(function(response) {
return response.json();
});
}));
Now promise.then
will give you access to an array of the data once all the promises have resolved. You don't need to push to another array, the .map
will create the array of promises for you.
You can also write this using the async
/ await
syntax which is easier to reason about and potentially cleaner.
const promise = Promise.all(users.map(async user => {
const url = `https://api.twitch.tv/helix/users?login=${user}`;
const response = await fetch(url, { headers });
return response.json();
}));
By the way, you should only need to use new Promise
when working with libraries that don't implement promises themselves. fetch
already returns a Promise, so when you call it you're already getting a promise back so there's no need to wrap it with new Promise
.
Solution 2:
To get the result you want, your code can be rewritten as
const users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"]
const headers = {
'Client-Id': 'xxxxxxxxxxx'
}
Promise.all(users.map(user => fetch(`https://api.twitch.tv/helix/users?login=${user}`, {headers}).then(response => response.json())))
.then(result => console.log(result));
A little more readable
const users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"]
const headers = {
'Client-Id': 'xxxxxxxxxxx'
}
const mapper = user =>
fetch(`https://api.twitch.tv/helix/users?login=${user}`, {headers})
.then(response => response.json());
const promises = users.map(mapper);
Promise.all(promises)
.then(result => console.log(result));
and, finally, since your original code shows no knowledge of ES2015+
var users = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var headers = {
'Client-Id': 'xxxxxxxxxxx'
};
var mapper = function mapper(user) {
return fetch("https://api.twitch.tv/helix/users?login=" + user, { headers: headers }).then(function (response) {
return response.json();
});
};
var promises = users.map(mapper);
Promise.all(promises).then(function (result) {
return console.log(result);
});
Solution 3:
do something like this instead:
const runTheTrap = async function(users){
const ret = [];
for (i = 0; i < users.length; i++) {
var url = "https://api.twitch.tv/helix/users?login=" + users[i];
await fetch(url, {headers})
.then(function(r) {
return r.json().then(v => ret.push(v));
});
};
return ret;
}
runTheTrap(users).then(function(result) {
console.log(result);
});
but frankly async/await is kinda 'tarded, I prefer this approach:
const runTheTrap = function(users){
return users.map(function(u){
var url = "https://api.twitch.tv/helix/users?login=" + u;
return fetch(url, {headers}).then(r => {
return r.json();
});
}
Promise.all(runTheTrap(users)).then(function(vals){
// you have your vals
});
Post a Comment for "I'm Trying To Understand How To Use Promises In Javascript, But My Script Never Executes The "Then""