coroutines_promises_and_futures.js (1887B)
1 // Promises in JavaScript and futures and in Rust are two different implementations that are based on the same idea. 2 // 3 // Promises are one way to deal with the complexity that comes with 4 // a callback-based approach. 5 6 7 // Instead of: 8 setTimer(200, () => { 9 setTimer(100, () => { 10 setTimer(50, () => { 11 console.log("I'm the last one"); 12 }); 13 }); 14 }); 15 16 // We can do: 17 // 18 // You see, promises return a State Machine that can be in one of 19 // three states: Pending, Fullfilled, or Rejected. 20 function timer(ms) { 21 return new Promise((resolve) => setTimeout(resolve, ms)); 22 } 23 // This is referred to as the continuation-passing style. 24 // Each subtask calls a new one once it's finished. 25 timer(200) 26 .then(() => timer(100)) 27 .then(() => timer(50)) 28 .then(() => console.log("I'm the last one")); 29 30 // Coroutines and async/await 31 // 32 // - Async: the compiler rewrites what looks like a normal function 33 // call into a `future` (in Rust) or a `promise` (in JavaScript). 34 // 35 // - Await, yields control to the runtime scheduler, and the task 36 // is suspended until the future/promise you're awaiting 37 // has finished. 38 // 39 // This way, we can write programs that handle concurrent operations 40 // in almost the same way we write our normal sequential programs. 41 // 42 // You can consider the run function as a pausable task consisting 43 // of several sub-tasks. On each "await" point, it yields control to the scheduler (in this case, it's the JavaScript event loop). 44 // 45 // Once one of the sub-tasks changes state to either `fullfilled` or 46 // `rejected`, the task is scheduled to continue to the next step. 47 async function run() { 48 await timer(200); 49 await timer(100); 50 await timer(50); 51 console.log("I'm the last one"); 52 } 53 54 // In Rust, you can see the same transformation happening with the 55 // function signature: 56 // 57 // From: 58 // async fn run() -> () {...} 59 // 60 // To: 61 // Fn run() -> impl Future<Output = ()>