Open danielrousseaug opened 3 years ago
This isn't so much an issue with my library, but more a javascript question.
What you pass to then
itself is a function. The () => { }
is just syntactic sugar for an anonymous function declaration. You could rewrite it as the following:
thingy.then(function(value) {
const arr = value;
console.log(arr);
return arr;
});
When rewritten like this, it becomes clear that the return
actually refers to the inner, anonymous function, not the outer function getInfoByName
.
In addition, what's important to understand is that then
doesn't block. Node runs a big event loop, and when you pass a function to then
, it puts it on the event loop, waits until thingy
resolves, and then calls the function you passed into then
with the return values from the initial promise. In the meantime, getInfoByName
has already returned and finished.
Now, if you want to pass along the results of cli.get
through getInfoByName
, there are a couple of ways that you can accomplish this. Let's go through the options and talk about the upsides and downsides of each.
async
/await
We can make getInfoByName
and async function
, which means that it gets executed asynchronously, and won't return until cli.get
has fully resolves. This would look like the following:
async function getInfoByName(title) {
const arr = await cli.get({ 'name': title });
return arr;
}
Now, arr
is returned from getInfoByName
just like originally intended. But, it's important to understand that this doesn't magically make the asynchronous call to cli.get
synchronous. It now means that when getInfoByName
is called, it too will be executed asynchronously and added to the event loop that node started, so calling code will need to be prepared to call asynchronous code too.
What that means in practice, is getInfoByName
will only be callable from normal functions as a promise (and still executed asynchronously) or will only be callable with await
from async
functions. Some folks refer to this as function coloring due to this popular blog post: https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/
Promise
You don't have to use the fancy async
/await
syntax, and just return a Promise
. In that case, you'd now resolve getInfoByName
like any other function that returns a Promise
: by calling then
or catch
or whatever on it. This'd look roughly like:
function getInfoByName(title) {
return cli.get({'name': title});
}
Here, you're just forwarding along the Promise
that I returned, and calling code will be able to chain .then
calls to extract the data.
Finally, the most important part of this, is that 1 & 2 are the same option. async
functions are just syntactic sugar for wrapping your return value in a Promise
object if it isn't already a Promise
.
Let's look at this trivial jsfiddle: https://jsfiddle.net/cd7x6kvh/
If you look at the js console after running it, you can see that even though we told our function foo
to return a simple integer, it's actually returning a Promise
. async
/await
certainly makes it nicer to pretend that it's closer to being synchronous, but that's really just a sweet lie. You're still dealing with Promise
objects at the end of the day.
Let me know if that helped or if you have other questions!
@worr I found this library today and just wanted to say you taking your time and carefully explaining The async concept to this dude is the most wholesome thing I've seen on github. Big ups to you man!
It logs properly but returns
undefined
. I don't understand why it waits to resolve the promise forconsole.log
but not forreturn
, sorry for the unnecessary issue but I'm desperate.