惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MyScale Blog
MyScale Blog
MongoDB | Blog
MongoDB | Blog
The Register - Security
The Register - Security
T
The Blog of Author Tim Ferriss
A
About on SuperTechFans
Vercel News
Vercel News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Jina AI
Jina AI
Stack Overflow Blog
Stack Overflow Blog
Cisco Talos Blog
Cisco Talos Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
W
WeLiveSecurity
S
Securelist
I
Intezer
F
Full Disclosure
WordPress大学
WordPress大学
腾讯CDC
酷 壳 – CoolShell
酷 壳 – CoolShell
Latest news
Latest news
aimingoo的专栏
aimingoo的专栏
C
Cisco Blogs
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
The Exploit Database - CXSecurity.com
P
Proofpoint News Feed
K
Kaspersky official blog
阮一峰的网络日志
阮一峰的网络日志
P
Proofpoint News Feed
J
Java Code Geeks
人人都是产品经理
人人都是产品经理
雷峰网
雷峰网
AWS News Blog
AWS News Blog
T
Tenable Blog
Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
L
LINUX DO - 最新话题
小众软件
小众软件
T
Threat Research - Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
The GitHub Blog
The GitHub Blog
爱范儿
爱范儿
N
News and Events Feed by Topic
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
量子位
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Forbes - Security
Forbes - Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
U
Unit 42
O
OpenAI News
V
V2EX
T
Troy Hunt's Blog

ValeriaVG

Agentic Development Survival Guide Simplicity Police The sunset of Arrogance as a Service How do I delegate when I can do it faster myself? Implementing custom Calendar component Plug & Play Modular Architecture for Scalable and Maintainable Apps ES Modules & Import Maps: Back to the Future Me & React: 5 Years in 15 Minutes 10 Reasons NOT to Use Go for Your Next Project How Build a Web App in 11 Minutes and Fall in Love With Sveltekit Master Git in 7 Minutes Crc 32 Checksum in Wasm and Raw Js Tutorial and Benchmark Master Binary in Five Minutes How to Use Custom Files as Modules in Nodejs How to Do Magic With Numbers 5 Ways to Use Redis in Your Next Project
Five Pro Tips to Master Promises in Js
Valeria Viana Gusmao · 2021-06-05 · via ValeriaVG

Events handling and promises in particular are hands down the best JavaScript feature. You're probably familiar with the concept itself, but in short, a Promise in JavaScript is a promise to call back with the result.

Therefore, a promise can be constructed with two functions: one to be called on success and the other - in case of error. Here is a promise that would randomly fail or reject after one second:

const promise = new Promise((resolve, reject) => { setTimeout(() => { const randomBool = Math.random() > 0.5; console.log(randomBool); // Return any value, or no value at all if (randomBool) resolve("I am resolved!"); // Reject with an error, some value or nothing at all else reject("On no!"); }, 1_000); });

Try this in your browser console or in node repl (run node with no arguments). You should see true or false logged to a console after a second and, if promise failed, you'll see an error message (or a warning that promise was not caught in node). Now that we got something to play with, the tips I've promised (pun intended):

Tip #1: Promise starts right away

As you've seen in the example, a promise will resolve or reject even if it have not been chained with .then, .catch or await. As soon as you've created the promise, it'll start doing whatever it had been told to do.

Tip #2: Once complete, promise will yield the same result over and over

Try running promise.then(console.log) in the same console or repl where you defined the promise from previous example. It'll log the exact same result over and over, without a delay. Try logging console.log(promise), what do you see? I bet it's either:

Promise {<rejected>: "On no!"}

Or , if it has resolved,:

Promise { "I am resolved!" }

You've probably guessed by now, that a promise can be in one of the three states: pending,rejected or fulfilled (resolved to a value). The trick here is that it'll stay in its final state till the garbage collector wipes it from existence 🪦.

Tip #3: Promise.prototype.then accepts two callbacks

You can get promise results by chaining then and catch to it:

promise.then(console.log).catch(console.error);

Or, simply:

promise.then(console.log, console.error);

Tip #4: Promise.prototype.then and Promise.prototype.catch return a new promise

If you console.log(promise.then(()=>{},()=>{})), you'll get Promise { <pending> }, even if the promise have been resolved. This, however, does not mean that the async operation itself will be retried, just that these methods always create a new promise, even if your callback functions are synchronous.

promise === promise.then( () => {}, () => {} ); // false promise === promise.then( () => promise, () => promise ); // false

Tip #5: Use Promise.all, Promise.race and async/await when appropriate

Before ES5 introduced async-await syntax we all lived in a callback hell:

promise.then(() => { promise.then(() => { promise.then(() => { promise.then(() => { console.warn("Callback hell in action"); }); }); }); });

But it's important to remember that async/await is just a syntax sugar over that construction. In it's core, it still is the same chain, meaning that the next promise won't be created until the previous one is fulfilled:

const createTimeoutPromise = (n, timeout) => new Promise((resolve) => setTimeout(() => { console.log(`Promise #${n} is fulfilled`); resolve(n); }, timeout) ); (async () => { const now = Date.now(); await createTimeoutPromise(1, 1_000); await createTimeoutPromise(2, 1_000); await createTimeoutPromise(3, 1_000); console.log(`Operation took`, ((Date.now() - now) / 1_000).toFixed(1), "s"); })(); // Promise #1 is fulfilled // Promise #2 is fulfilled // Promise #3 is fulfilled // Operation took 3.0 s

Therefore, if you just want it all done, no matter in what order, use Promise.all to speed things up:

(async () => { const now = Date.now(); const results = await Promise.all([ createTimeoutPromise(1, 1_000), createTimeoutPromise(2, 999), createTimeoutPromise(3, 998), ]); console.log(results); console.log(`Operation took`, ((Date.now() - now) / 1_000).toFixed(1), "s"); })(); // Promise #3 is fulfilled // Promise #2 is fulfilled // Promise #1 is fulfilled // [ 1, 2, 3 ] // Operation took 1.0 s

As you can see, you'll still get the results of the promises in the same order as you specified them, despite of the order in which they were fulfilled.

In rare cases, you may not need all of your promises to fulfil, but any of them. Let them Promise.race for the sire's favour 👑:

(async () => { const now = Date.now(); const results = await Promise.race([ createTimeoutPromise(1, 1_000), createTimeoutPromise(2, 999), createTimeoutPromise(3, 998), ]); console.log(results); console.log(`Operation took`, ((Date.now() - now) / 1_000).toFixed(1), "s"); })(); // Promise #3 is fulfilled // 3 // Operation took 1.0 s // Promise #2 is fulfilled // Promise #1 is fulfilled

Keep in mind, that if any of the promises fail, both Promise.all and Promise.race will reject.

That's all I had for today, but I promise there'll be more (see what I did here?).