I am wanting a to call this to save a variable as an array by calling a function to create the array by key presses
moves = xenet().getDirections("3000");
console.log("Your moves were " moves);
And the JavaScript works it just returns undefined and way to early so what am I doing wrong.
getDirections: (duration) => {
let moves = [];
let on = true;
if (on == true) {
window.addEventListener('keydown', keyPress, true);
console.log("Getting Directions");
// Code Returns Right here
function keyPress(e) {
if (e.key == "w", e.key == "ArrowUp") {moves.push("Up")}
if (e.key == "a", e.key == "ArrowLeft") {moves.push("Left")}
if (e.key == "s", e.key == "ArrowDown") {moves.push("Down");}
if (e.key == "d", e.key == "ArrowRight") {moves.push("Right");}
console.log("Key pressed");
}
setTimeout(function() {
on == false;
window.removeEventListener("keydown", keyPress, true);
console.log("Stopped getting directions");
return moves; // I want the code to return the created array right here
}, duration);
}
}
CodePudding user response:
There are multiple issues here:
- At the call site, your duration is a
string
-- it should be anumber
- You don't return anything from
getDirections
- Even if you did try to return from
getDirections
,setTimeout
is asynchronous, so the return wouldn't work as expected. - You should use
===
for comparisons like this - The
OR
operator is||
, not,
Here's an updated, working version. It uses a "completion handler" which calls a function when the setTimeout
is complete.
const getDirections = (duration, completion) => {
let moves = [];
function keyPress(e) {
if (e.key === "w" || e.key === "ArrowUp") {moves.push("Up")}
if (e.key === "a" || e.key === "ArrowLeft") {moves.push("Left")}
if (e.key === "s" || e.key === "ArrowDown") {moves.push("Down");}
if (e.key === "d" || e.key === "ArrowRight") {moves.push("Right");}
console.log("Key pressed");
}
window.addEventListener('keydown', keyPress, true);
console.log("Getting Directions");
setTimeout(function() {
window.removeEventListener("keydown", keyPress, true);
console.log("Stopped getting directions");
completion(moves); // I want the code to return the created array right here
}, duration);
}
getDirections(10000, moves => console.log("Moves:",moves))
CodePudding user response:
setTimeout is an asynchronous function. You cannot return a value from an async function synchronously. The function executing the setTimeout (getDirections) will finish executing before the callback passed to setTimeout is called. To accomplish what you are trying to do, you need to use Promises or async/await.
For example:
async function getDirections(duration){
let moves = [];
let on = true;
if (on == true) {
window.addEventListener('keydown', keyPress, true);
console.log("Getting Directions");
function keyPress(e) {
if (e.key == "w", e.key == "ArrowUp") {moves.push("Up")}
if (e.key == "a", e.key == "ArrowLeft") {moves.push("Left")}
if (e.key == "s", e.key == "ArrowDown") {moves.push("Down");}
if (e.key == "d", e.key == "ArrowRight") {moves.push("Right");}
console.log("Key pressed");
}
var promise = new Promise(function(resolve, reject) {
window.setTimeout(function() {
on = false;
window.removeEventListener("keydown", keyPress, true);
console.log("Stopped getting directions");
resolve(moves);
}, duration);
});
return promise;
}
}
async function getResult() {
const result = await getDirections("3000");
console.log("Your moves were " result)
}
getResult();