Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript Promises: chaining promises with non-promise objects. Why it works?

I'm learning about JavaScript Fetch API and I'm a bit confusing about Promises.

Consider this dummy example that prints "ok" in the console:

fetch(".")
.then(function(response) { // first then() call
    return response;
}).then(function(response) { // second then() call
    console.log("ok");
});

The page about the Response Object of the Fetch API says:

The fetch() call returns a promise, which resolves with the Response object associated with the resource fetch operation.

Well, since fetch() returns a Promise object I can understand that the first then() call works fine because a Promise object has this method. But the Response object returned in the chained call is not a Promise object. However the second call to then() method works!

Altering the dummy example prints undefined in the first console.log():

fetch(".")
.then(function(response) { // first then() call
    console.log(response.then)
    return response;
}).then(function(response) { // second then() call
    console.log("ok");
});

My questions is: Why this works? How the second call to then() works since the returned object does not have this method? Is it a kind of syntax sugar?

Thanks!

like image 797
Bruno Peres Avatar asked May 17 '17 02:05

Bruno Peres


1 Answers

But the Response object returned in the chained call is not a Promise object. However the second call to then() method works!

Yes, because the second .then() invocation is on the return value of the first then call, not on the response. The promise then method always returns a promise - which makes it chainable. It does not return the return value of the asynchronous callback - for that it would need to peek into the future.

Look closely:

const promise1 = fetch(".");
const promise2 = promise1.then(function(response) { // first then() call
    return response;
});
const promise3 = promise2.then(function(response) { // second then() call
    console.log("ok");
});

It's not

fetch(".").then(function(response) { // outer then() call
    return response.then(function() { // inner then() call
        console.log("ok");
    });
});

which indeed doesn't work without response being a promise.

like image 120
Bergi Avatar answered Oct 22 '22 11:10

Bergi