|
1 | 1 | # Promises |
2 | 2 |
|
| 3 | +## Async JavaScript Primer |
| 4 | + |
| 5 | +JavaScript runs your code on a single main thread. If a task takes time (like |
| 6 | +waiting for a network response, reading a file, or a timer), the language uses |
| 7 | +asynchronous APIs to keep the main thread free so the app can stay responsive. |
| 8 | + |
| 9 | +In practice, this means: |
| 10 | + |
| 11 | +- **Synchronous code** runs top to bottom and blocks until it finishes. |
| 12 | +- **Asynchronous code** starts work now and delivers results later. |
| 13 | + |
| 14 | +The call stack tracks which functions are currently running. Synchronous work |
| 15 | +stays on the call stack until it completes. Asynchronous work registers a |
| 16 | +callback, returns immediately, and the callback only runs later when the call |
| 17 | +stack is clear. |
| 18 | + |
| 19 | +If you want a visual to explore how promise chains behave over time, check out |
| 20 | +the Promisees playground at https://bevacqua.github.io/promisees/. It only runs |
| 21 | +JavaScript (not TypeScript), so paste the JavaScript version of the example |
| 22 | +below. |
| 23 | + |
| 24 | +```ts |
| 25 | +// Synchronous: runs in order, one step at a time. |
| 26 | +console.log('A') |
| 27 | +console.log('B') |
| 28 | +console.log('C') |
| 29 | +``` |
| 30 | + |
| 31 | +```ts |
| 32 | +// Asynchronous: timer finishes later. |
| 33 | +console.log('Start') |
| 34 | +setTimeout(() => console.log('Later'), 0) |
| 35 | +console.log('End') |
| 36 | +// Output: |
| 37 | +// Start |
| 38 | +// End |
| 39 | +// Later |
| 40 | +``` |
| 41 | + |
| 42 | +```ts |
| 43 | +// A promise represents "later". |
| 44 | +function getNumber() { |
| 45 | + return new Promise<number>((resolve) => { |
| 46 | + setTimeout(() => resolve(42), 100) |
| 47 | + }) |
| 48 | +} |
| 49 | + |
| 50 | +getNumber().then((value) => console.log('Value:', value)) |
| 51 | +``` |
| 52 | + |
| 53 | +```ts |
| 54 | +// Promises chain, so each step waits for the previous one. |
| 55 | +function fetchUser() { |
| 56 | + return Promise.resolve({ id: 1, name: 'Alice' }) |
| 57 | +} |
| 58 | + |
| 59 | +fetchUser() |
| 60 | + .then((user) => user.name) |
| 61 | + .then((name) => name.toUpperCase()) |
| 62 | + .then((upper) => console.log(upper)) |
| 63 | +``` |
| 64 | + |
| 65 | +```js |
| 66 | +// A longer chain you can tweak and observe over time. |
| 67 | +function getDelayedNumber(label, value, delay) { |
| 68 | + return new Promise((resolve) => { |
| 69 | + setTimeout(() => { |
| 70 | + console.log(`${label}: ${value}`) |
| 71 | + resolve(value) |
| 72 | + }, delay) |
| 73 | + }) |
| 74 | +} |
| 75 | + |
| 76 | +getDelayedNumber('first', 2, 150) |
| 77 | + .then((value) => getDelayedNumber('double', value * 2, 300)) |
| 78 | + .then((value) => getDelayedNumber('plus five', value + 5, 200)) |
| 79 | + .then((value) => getDelayedNumber('square', value * value, 250)) |
| 80 | + .then((value) => { |
| 81 | + if (value > 100) { |
| 82 | + throw new Error('Value is too large') |
| 83 | + } |
| 84 | + return getDelayedNumber('half', value / 2, 150) |
| 85 | + }) |
| 86 | + .then((value) => console.log('final value', value)) |
| 87 | + .catch((error) => console.error('chain failed', error)) |
| 88 | +``` |
| 89 | + |
| 90 | +Try pasting that chain into the Promisees playground to see how each step |
| 91 | +waits, resolves, or throws as you tweak the delays and values. |
| 92 | + |
| 93 | +Promises are the standard way to represent that "later" value. You can attach |
| 94 | +handlers for success and failure, and you can combine multiple async operations |
| 95 | +without getting lost in nested callbacks. |
| 96 | + |
3 | 97 | Promises are the foundation of asynchronous programming in JavaScript and |
4 | 98 | TypeScript. They represent a value that will be available in the future—either |
5 | 99 | a successful result or a failure. |
6 | 100 |
|
7 | 101 | ```ts |
8 | 102 | // A Promise that resolves to a string |
9 | | -const fetchUser = (): Promise<string> => { |
| 103 | +function fetchUser(): Promise<string> { |
10 | 104 | return new Promise((resolve) => { |
11 | 105 | setTimeout(() => resolve('Alice'), 1000) |
12 | 106 | }) |
|
0 commit comments