What it does: Links promises together so each .then() waits for the previous one to finish and passes data down the chain.

How Chaining Works:

Basic Chain - Return Values:

new Promise(resolve => resolve(1))
  .then(result => {
    console.log(result); // 1
    return result * 2;   // passes 2 to next .then
  })
  .then(result => {
    console.log(result); // 2
    return result * 2;   // passes 4 to next .then
  })
  .then(result => {
    console.log(result); // 4
  });

Chain with Promises - Return Promises:

loadScript('1.js')
  .then(script => {
    return loadScript('2.js'); // return another promise
  })
  .then(script => {
    return loadScript('3.js'); // chain waits for this
  })
  .then(script => {
    console.log("All scripts loaded!");
  });

Chaining vs Multiple Handlers:

❌ Multiple handlers (NOT chaining):

let promise = Promise.resolve(1);
promise.then(result => console.log(result)); // 1
promise.then(result => console.log(result)); // 1  
promise.then(result => console.log(result)); // 1
// All get same original result!

✅ Actual chaining:

Promise.resolve(1)
  .then(result => result * 2)  // 2
  .then(result => result * 2)  // 4
  .then(result => result * 2); // 8
// Each gets result from previous step!

Real Example - fetch():

fetch('/user.json')
  .then(response => response.json())    // parse JSON
  .then(user => fetch(`/users/${user.id}/posts`)) // another request
  .then(response => response.json())    // parse again
  .then(posts => console.log(posts));   // final data

Interview Gotchas:

// 1. Forgetting to return
promise
  .then(result => {
    doSomething(result); // forgot return!
  })
  .then(result => {
    console.log(result); // undefined!
  });
 
// 2. Returning vs not returning promises
.then(data => processData(data))        // ✅ returns promise
.then(data => { processData(data); })   // ❌ returns undefined
 
// 3. Nested vs chained
.then(data => {
  return fetch('/api').then(response => response.json()); // nested ❌
})
.then(data => fetch('/api'))
.then(response => response.json()); // flat chaining ✅

Bottom line: Each .then() creates a new promise. Return values become the next promise’s result. Return promises to wait for async operations. Always return something to keep the chain going.