czyykj.com

Mastering Promises: 8 Advanced Techniques for JavaScript

Written on

Chapter 1: Understanding Promises in Depth

In JavaScript development, promises are a fundamental concept that should not be overlooked. Surprisingly, many mid-level and senior front-end developers rely heavily on basic methods like promiseInst.then(), promiseInst.catch(), Promise.all, and even async/await, often without a comprehensive understanding of their workings. This guide presents advanced techniques for using promises, many of which are actively employed in the ALOVA request strategy library. By the end of this, you should feel confident in tackling any related queries.

Section 1.1: Executing Promises Sequentially

To execute a series of API calls in order, one might instinctively consider using await. For instance:

const requestAry = [() => api.request1(), () => api.request2(), () => api.request3()];

for (const requestItem of requestAry) {

await requestItem();

}

Alternatively, using promise chaining can achieve the same effect:

const requestAry = [() => api.request1(), () => api.request2(), () => api.request3()];

const finalPromise = requestAry.reduce(

(currentPromise, nextRequest) => currentPromise.then(() => nextRequest()),

Promise.resolve() // Start with a resolved promise

);

Section 1.2: Managing State Outside Promise Scope

Consider a scenario where you need to gather user information before utilizing certain functionalities. Different developers approach this in varying ways:

  • Junior Developer: "I'll create a modal and copy it across pages for efficiency!"
  • Intermediate Developer: "That's not maintainable; we should encapsulate this component and import it where needed."
  • Senior Developer: "Let’s encapsulate everything that needs encapsulating! Writing it in a single place for universal access is far more efficient."

Here’s a Vue3 example from a Senior Developer demonstrating how to implement this effectively:

getInfoByModal(); // This method directly calls the modal to collect user data.

This showcases how commonly used components can be encapsulated within UI libraries.

Section 1.3: Alternative Uses of Async/Await

Many developers limit their use of await to receiving return values from "async functions," failing to recognize that an async function inherently returns a promise. For instance, the following functions are equivalent:

const fn1 = async () => 1;

const fn2 = () => Promise.resolve(1);

Both functions will yield a promise resolving to 1. Moreover, if await is followed by a non-promise value, it will convert this value into a promise object, ensuring the subsequent code executes asynchronously:

Promise.resolve().then(() => {

console.log(1);

});

await 2; // Executes asynchronously

console.log(2);

The output sequence will be: 1 2.

The first video, Efficient Meetings - 7 Tips To Run an Effective Meeting, offers insights into improving meeting productivity.

Section 1.4: Sharing Requests with Promises

To avoid redundant requests when a response is pending, we can share the response from the first request with subsequent ones. For example:

request('GET', '/test-api').then(response1 => {

// Handle response

});

request('GET', '/test-api').then(response2 => {

// Handle response

});

In this case, both requests will be sent once, sharing the same response. This technique is beneficial in scenarios such as:

  • Rendering multiple components that fetch data simultaneously.
  • Users clicking the submit button multiple times before disabling it.
  • Preloading data before transitioning to the relevant page.

This is one of Alova's advanced features, which incorporates promise caching for managing requests. The implementation could look like this:

const pendingPromises = {};

function request(type, url, data) {

const requestKey = JSON.stringify([type, url, data]);

if (pendingPromises[requestKey]) {

return pendingPromises[requestKey];

}

const fetchPromise = fetch(url, {

method: type,

body: JSON.stringify(data)

})

.then(response => response.json())

.finally(() => {

delete pendingPromises[requestKey];

});

return pendingPromises[requestKey] = fetchPromise;

}

Section 1.5: Understanding Promise States

It's essential to know that promises can only transition from "pending" to either "fulfilled" or "rejected." Consider the following example:

const promise = new Promise((resolve, reject) => {

resolve();

reject(); // This call is ignored; the promise remains fulfilled.

});

Thus, once a promise is fulfilled, it cannot revert to a pending state.

Section 1.6: Clarifying then, catch, and finally

In summary, all three functions return a new promise object. If an error occurs, it transitions to a rejected state. Here’s a concise example to illustrate their behavior:

// then function

Promise.resolve().then(() => 1); // Returns a promise resolved with 1

Promise.reject().then(() => 2).catch(() => 3); // Returns 3

Section 1.7: Differences in Error Handling

While both the second callback of then and catch handle errors, the former cannot catch errors thrown in the first callback:

Promise.resolve().then(

() => {

throw new Error('Error from successful callback');

},

() => {

// This won't execute

}

).catch(reason => {

console.log(reason.message); // Outputs: "Error from successful callback"

});

Section 1.8: Implementing Promises in Koa2 Middleware

Koa2 utilizes an onion model for processing requests, allowing for layered handling of middleware. Here’s a simple implementation:

const app = new Koa();

app.use(async (ctx, next) => {

console.log('Layer A Start');

await next();

console.log('Layer A End');

});

app.use(async (ctx, next) => {

console.log('Layer B Start');

await next();

console.log('Layer B End');

});

app.listen(3000);

The output sequence will be: Layer A Start -> Layer B Start -> Layer B End -> Layer A End.

The second video, How to have more effective and productive meetings, provides strategies for improving meeting efficiency.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Transformative Insights: How Rejected Papers Reshape Science

Explore how rejected scientific papers, like Crick's, redefine our understanding of biology and the role of serendipity in research.

Innovative Strategies for Creative Business Success

Explore unconventional methods to enhance creativity and maximize ROI in business.

A Comprehensive Guide to Achieving Happiness and Fulfillment

Discover a structured approach to enhance your health, relationships, and wealth for a more fulfilling life.

5 Million Dollar Sales Lessons I Learned Through Experience

Discover five crucial sales lessons learned through hard-earned experience that can transform your business approach and boost your revenue.

Transformative Journeys: How Rapid Change Can Shape Our Lives

A personal account of how sudden changes can lead to profound transformation and resilience.

Understanding the Escalating Consequences of Climate Change

Explore the alarming impacts of climate change, from rising temperatures to severe droughts and their global implications.

Mastering Wealth: Strategies for Financial Success in Your 20s

Discover actionable strategies to enhance your financial situation and build wealth effectively, even in your 20s.

Understanding the Top Malware Threats of 2021

An overview of the major malware strains identified by US and Australian cybersecurity agencies and their implications.