I'm playing around with setTimeout, and I'm not getting the results I'd expect. I have an array by the name of cars, and I have a function called fetchCars which simply calls setTimeout and returns the cars after 1000 ms. As far as I know the setTimeout should have access to the cars array because of closures, but for some reason when I an await an invocation of fetchCars I don't get any results.
Here is a sandbox Here is my code:
const cars = [
{ brand: "Toyota", model: "Camry", year: "2014" },
{ brand: "BMW", year: "2016", model: "M3" },
{ brand: "Porche", model: "911", year: "2018" }
];
export const fetchCars = async () => {
setTimeout(() => {
return cars;
}, 1000);
};
const recieveCars = async () => {
const cars = await fetchCars();
console.log(cars);
};
recieveCars();
///Console Output: undefined
CodePudding user response:
The reason you're seeing undefined
in your console is that fetchCars
returns a Promise (only by virtue that you have tagged it with async
) that resolves to undefined - in other words, it doesn't really return anything!
export const fetchCars = async () => {
setTimeout(() => {
// the callback you have passed to setTimeout will return cars, not the fetchCars function
return cars;
}, 1000);
};
If you want fetchCars
to return a value, it needs to return a Promise that will resolve to the value you want to return.
// no need for async here, because we're going to be returning a Promise explicilty
export const fetchCars = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(cars);
}, 1000);
});
};
CodePudding user response:
setTimeout
uses a callback and has no native Promise
version. While Brendan's answer is correct and perfectly functional, another option that is more consistent with async/await
style is to await
the timeout promise in the async
function, then return the value.
export const fetchCars = async () => {
await new Promise((r) => setTimeout(r, 1000);
return cars;
};
If you're doing this a lot, a convenience function like this:
const delay = (delayTime) => new Promise((r) => setTimeout(r, delayTime));
Will then let you write your function like:
export const fetchCars = async () => {
await delay(1000);
return cars;
};