1

The context is this: I have a 'toy' node.js server that returns the following json: { "message" : "hello there" } And this is returned if you do a GET request to "http://localhost:3060/" So, very simple.

Here is my 'baseline' code, featuring multiple .then(..) clauses

 3 function footgun() { 4 fetch('http://localhost:3060/') 5 .then(res => res.json()) 6 .then(json => json.message) 7 .then(msg => console.log(msg)); 

The output is: hello there

Excellent. Very good. That's what I wanted.

I have been reading about how promises are implemented.
And so I know that each .then() returns a Promise object. But isn't that wasteful ?
Surely it would be more efficient to pack everything into one .then() clause ? Like this:

 3 function footgun() { 4 fetch('http://localhost:3060/') 5 .then(res => { 6 const json = res.json(); 7 const msg = json.message; 8 console.log(msg); 9 }); 

The output is: undefined

That's the problem. Why is the result 'undefined' ? Why does this not work inside a single .then(..) clause ?

Thanks to anyone that volunteers an explanation or suggestion. :-) Gene Keto

4

1 Answer 1

3

You should only use an additional .then() when you have another asynchronous operation that you need the result of.

So, in this:

 3 function footgun() { 4 fetch('http://localhost:3060/') 5 .then(res => res.json()) 6 .then(json => json.message) 7 .then(msg => console.log(msg)); 

You need a .then() for fetch() and you need one for res.json() as both are asynchronous and both return a promise.

You do NOT need this one:

.then(json => json.message) 

as it just wastes a few cycles that you don't need to do. In the sequence you've shown, this would be the most efficient:

 3 function footgun() { 4 fetch('http://localhost:3060/') 5 .then(res => res.json()) 6 .then(data => console.log(data.message)); 

You use a .then() ONLY for each asynchronous operation that returns a promise.


Of course, it's even simpler if you use await:

 3 async function footgun() { 4 let res = await fetch('http://localhost:3060/'); 5 let data = await res.json(); 6 console.log(data.message); 

Similarly, you only use await when you have an asynchronous operation that returns a promise.


In your second example that doesn't work:

 3 function footgun() { 4 fetch('http://localhost:3060/') 5 .then(res => { 6 const json = res.json(); 7 const msg = json.message; 8 console.log(msg); 9 }); 

res.json(); is an asynchronous operation that returns a promise that you never wait to resolve. So, json ends up being a promise (not your desired data). So, when you try to reference json.message it's undefined because json here is a promise and a promise doesn't have a .message property (thus you get undefined).

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.