I need to write a function which makes two chained HTTP calls and act upon the result once the results of the second call are available.
The approach I thought would works is
function getdata() {
return fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(r => r.json())
.then(r => fetch(`https://jsonplaceholder.typicode.com/todos/2`)
.then(s => s.json())
)
}
let m = getdata()
m.then(x => console.log(JSON.stringify(x)))
This works fine, the console output is as expected.
I then ported the idea to my actual call, the main difference being that the HTTPS calls are slow. For the sake of mapping the actual error to code, consider a small variation of the code above (with some logging added)
function getdata() {
return fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(r => r.json())
.then(r => fetch(`https://jsonplaceholder.typicode.com/todos/2`)
.then(s => {
console.log(s)
s.json()
})
)
}
let m = getdata()
m.then(x => console.log(x))
The console output (from my actual code) is similar to
11:36:56.388 undefined
11:36:56.456 filter-sentinels.js:42 Response {type: "cors", url: …}
In details:
- the first
undefined
is fromconsole.log(x)
- the second line is from
console.log(s)
It would seem that the Promise is resolved in the second line, which comes after the first one. This is normal, it is what promises are for.
What I do not understand is why the .then()
in m.then(x => console.log(x) ))
is executed when the promise is not resolved yet?
A note on the title: what I actually want to understand is whether I can treat a Promise being generated (let m = ...
) as something synchronous - in the sense that I can safely apply a then()
to it and what happens in the then()
will happen when relevant information is known (the HTTP call has returned).