Reputation: 85
I have started to play round with Node.js but I am having trouble with asynchronous functions I was able to make a game small game. But the only way I was able to get the asynchronous functions to work with the synchronous functions was to use global variables.
Example
var promptly = require("./promptly"); //needed for input {npm install promptly}
var firstName;
var lastName;
GetFirstName();
function GetFirstName() { //asynchronous function
promptly.prompt('You first name: ', function (err,value) {
firstName = value;
getLastName();
});
}
function getLastName() { //asynchronous function
promptly.prompt('You last name: ', function (err,value) {
lastName = value;
printName();
});
}
function printName() { //synchronous function
console.log(firstName+" "+lastName);
}
This works but my small game with 5 asynchronous function ended with 14 global variable. so my question is what is the right way of doing something like this?
Upvotes: 2
Views: 3629
Reputation: 7956
What @jfriend00 is referring to in his/her comment is that when you define a function, you can define parameters
that the function should take.
With that in mind, you could rewrite your code to something like this:
var promptly = require("./promptly"); //needed for input {npm install promptly}
GetFirstName();
function GetFirstName() { //asynchronous function
promptly.prompt('You first name: ', function (err,firstName) {
getLastName(firstName);
});
}
function getLastName(firstName) { //asynchronous function
promptly.prompt('You last name: ', function (err,lastName) {
printName(firstName, lastName);
});
}
function printName(firstName, lastName) { //synchronous function
console.log(firstName+" "+lastName);
}
Note that each 'step' of the process accepts the result from the previous 'step'.
The async technique you're using is affectionately known as callback hell
, as the callback
s (i.e., the functions
you're passing to .prompt()
as the second argument) tend to nest deeply & quickly become unmanageable.
Javascript these days has a lot of solutions to manage this problem. Once you understand the 'flow' of an async program, I recommend looking into some of the more user-friendly options (take my snippets with a grain of salt, they're just meant to illustrate concepts):
async.js - this library has a lot of great utilities that help you write callbacks in more readable ways:
async.series([
asyncFunction1(arg, callback) {
// code
callback()
},
asyncFunction2(arg, callback) {
// code
callback()
},
asyncFunction3(arg, callback) {
// code
callback()
}
]
Promises - a new feature in Javascript and one already supported by libraries. Under the hood these are interesting, but in practice they simply allow for cleaner code and error handling:
asyncFunction1(args) {
// code
return x
}
.then(asyncFunction2(x) {
// code
return y
})
.then(asyncFunction3(y) {
// code
return z
})
async/await - one of the latest attempts at solving the async code challenge. Personally I haven't used them yet but the examples are interesting.
async function getName() {
let firstName = await getFirstName()
let lastName = await getLastName()
console.log("Your name is " + firstName + lastName)
}
The last article I linked is definitely worth a read for a good overview of the async challenge. It's not a simple concept to grok, but once it clicks, it's pretty intuitive.
Upvotes: 2
Reputation: 1380
Pass firstName
into getLastName()
and then pass firstName
and lastName
into printName()
. Here is some example code:
var promptly = require("promptly");
GetFirstName();
function GetFirstName() {
promptly.prompt('You first name: ', function (err,value) {
getLastName(value);
});
}
function getLastName(firstName) {
promptly.prompt('You last name: ', function (err,value) {
printName(firstName, value);
});
}
function printName(firstName, lastName) {
console.log(firstName + " " + lastName);
}
Upvotes: 0