国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Home Web Front-end JS Tutorial Create your own Promise in JavaScript

Create your own Promise in JavaScript

Dec 28, 2024 pm 01:29 PM

Create your own Promise in JavaScript

Why?

To get some idea how JavaScript Promises run callbacks asynchronously under the hood.

Let's create our own Promise in JavaScript! We'll follow the Promise/A specification, which outlines how promises handle async operations, resolve, reject, and ensure predictable chaining and error handling.

To keep things simple, we'll focus on the key rules marked by ? in the Promises/A specification. This won't be a full implementation, but a simplified version. Here's what we'll build:

1. Terminology

1.1 'promise' is an object or function with a then method whose behavior conforms to this specification.

1.2 thenable' is an object or function that defines a then method.

1.3 'value' is any legal JavaScript value (including undefined, a thenable, or a promise).

1.4 'exception' is a value that is thrown using the throw statement.

1.5 'reason' is a value that indicates why a promise was rejected.

2. Requirements

2.1 Promise States

A promise must be in one of three states: pending, fulfilled, or rejected.

2.1.1. When pending, a promise: ?

? may transition to either the fulfilled or rejected state.

2.1.2. When fulfilled, a promise: ?

? must not transition to any other state.

? must have a value, which must not change.

2.1.3. When rejected, a promise: ?

? must not transition to any other state.

? must have a reason, which must not change.

2.2 The then Method

A promise must provide a then method to access its current or eventual value or reason.

A promise's then method accepts two arguments:

2.2.1. Both onFulfilled and onRejected are optional arguments: ?

? If onFulfilled is not a function, it must be ignored.

? If onRejected is not a function, it must be ignored.

2.2.2. If onFulfilled is a function: ?

? it must be called after promise is fulfilled, with promise's value as its first argument.

? it must not be called before promise is fulfilled.

? it must not be called more than once.

2.2.3. If onRejected is a function, ?

? it must be called after promise is rejected, with promise's reason as its first argument.

? it must not be called before promise is rejected.

? it must not be called more than once.

2.2.4. onFulfilled or onRejected must not be called until the execution context stack contains only platform code. ?

2.2.5. onFulfilled and onRejected must be called as functions (i.e. with no this value). ?

2.2.6. then may be called multiple times on the same promise. ?

? If/when promise is fulfilled, all respective onFulfilled callbacks must execute in the order of their originating calls to then.

? If/when promise is rejected, all respective onRejected callbacks must execute in the order of their originating calls to then.

2.2.7. then must return a promise. ?

? If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x). ?

? If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason. ?

? If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value as promise1. ?

? If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason as promise1. ?

Implementation

A JavaScript Promise takes an executor function as an argument, which is called immediately when the Promise is created:

The core Promises/A specification does not deal with how to create, fulfill, or reject promises. It's up to you. But the implementation you provide for the promise's construction has to be compatible with asynchronous APIs in JavaScript. Here is the first draft of our Promise class:

Rule 2.1 (Promise States) states that a promise must be in one of three states: pending, fulfilled, or rejected. It also explains what happens in each of these states.

When fulfilled or rejected, a promise must not transition to any other state. Therefore, we need to ensure the promise is in the pending state before making any transition:

We already know that a promise's initial state is pending, and we ensure it remains so until explicitly fulfilled or rejected:

Since the executor function is called immediately upon the promise's instantiation, we invoke it within the constructor method:

Our first draft of the YourPromise class is done here.

The Promise/A specification mostly focuses on defining an interoperable then() method. This method lets us access the promise's current or eventual value or reason. Let's dive into it.

Rule 2.2 (The then Method) states that a promise must have a then() method, which accepts two arguments:

Both onFulfilled and onRejected must be called after the promise is fulfilled or rejected, passing the promise's value or reason as their first argument if they are functions:

Additionally, they must not be called before the promise is fulfilled or rejected, nor more than once. Both onFulfilled and onRejected are optional and should be ignored if they are not functions.

If you look at Rules 2.2, 2.2.6, and 2.2.7, you'll see that a promise must have a then() method, the then() method can be called multiple times, and it must return a promise:

To keep things simple, we won't deal with separate classes or functions. We'll return a promise object, passing an executor function:

Within the executor function, if the promise is fulfilled, we call the onFulfilled callback and resolve it with the promise's value. Similarly, if the promise is rejected, we call the onRejected callback and reject it with the promise's reason.

The next question is what to do with onFulfilled and onRejected callbacks if the promise is still in the pending state? We queue them to be called later, as follows:

We're done. Here's the second draft of our Promise class, including the then() method:

Here, we introduce two fields: onFulfilledCallbacks and onRejectedCallbacks as queues to hold callbacks. These queues are populated with callbacks via then() calls while the promise is pending, and they are called when the promise is fulfilled or rejected.

Go ahead test your Promise class:

It should output:

On the other hand, if you run the following test:

You would get:

Instead of:

Why? The issue lies in how the then() method processes callbacks when the YourPromise instance is already resolved or rejected at the time then() is called. Specifically, when the promise state is not pending, the then() method does not properly defer execution of the callback to the next micro-task queue. And that causes synchronous execution. In our example test:

? The promise is immediately resolved with the value 'Immediately resolved'.

? When promise.then() is called the state is already fulfilled, so the onFulfilled callback is executed directly without being deferred to the next micro-task queue.

Here the Rule 2.2.4 comes into play. This rule ensures that the then() callbacks (onFulfilled or onRejected) are executed asynchronously, even if the promise is already resolved or rejected. This means that the callbacks must not run until the current execution stack is completely clear and only platform code (like the event loop or micro-task queue) is running.

Why is this rule important?

This rule is one of the most important rules in the Promise/A specification. Because it ensures that:

? Even if a promise is immediately resolved, its then() callback won't execute until the next tick of the event loop.

? This behavior aligns with the behavior of the other asynchronous APIs in JavaScript such as setTimeout or process.nextTick.

How can we achieve this?

This can be achieved with either a macro-task mechanism such as setTimeout or setImmediate, or with a micro-task mechanism such as queueMicrotask or process.nextTick. Because the callbacks in a micro-task or macro-task or similar mechanism will be executed after the current JavaScript execution context finishes.

To fix the issue above, we need to ensure that even if the state is already fulfilled or rejected, the corresponding callbacks (onFulfilled or onRejected) are executed asynchronously using queueMicrotask. Here's the corrected implementation:

Run the previous example test code again. You should get the following output:

That's it.

By now, you should have a clear understanding of how callbacks from then() are deferred and executed in the next micro-task queue, enabling asynchronous behavior. A solid grasp of this concept is essential for writing effective asynchronous code in JavaScript.

What's next? Since this article didn't cover the full Promises/A specification, you can try implementing the rest to gain a deeper understanding.

Since you've made it this far, hopefully you enjoyed the reading! Please share the article.

Follow me on:
LinkedIn, Medium, and Github

The above is the detailed content of Create your own Promise in JavaScript. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Java vs. JavaScript: Clearing Up the Confusion Java vs. JavaScript: Clearing Up the Confusion Jun 20, 2025 am 12:27 AM

Java and JavaScript are different programming languages, each suitable for different application scenarios. Java is used for large enterprise and mobile application development, while JavaScript is mainly used for web page development.

Javascript Comments: short explanation Javascript Comments: short explanation Jun 19, 2025 am 12:40 AM

JavaScriptcommentsareessentialformaintaining,reading,andguidingcodeexecution.1)Single-linecommentsareusedforquickexplanations.2)Multi-linecommentsexplaincomplexlogicorprovidedetaileddocumentation.3)Inlinecommentsclarifyspecificpartsofcode.Bestpractic

How to work with dates and times in js? How to work with dates and times in js? Jul 01, 2025 am 01:27 AM

The following points should be noted when processing dates and time in JavaScript: 1. There are many ways to create Date objects. It is recommended to use ISO format strings to ensure compatibility; 2. Get and set time information can be obtained and set methods, and note that the month starts from 0; 3. Manually formatting dates requires strings, and third-party libraries can also be used; 4. It is recommended to use libraries that support time zones, such as Luxon. Mastering these key points can effectively avoid common mistakes.

Why should you place  tags at the bottom of the ? Why should you place tags at the bottom of the ? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript vs. Java: A Comprehensive Comparison for Developers JavaScript vs. Java: A Comprehensive Comparison for Developers Jun 20, 2025 am 12:21 AM

JavaScriptispreferredforwebdevelopment,whileJavaisbetterforlarge-scalebackendsystemsandAndroidapps.1)JavaScriptexcelsincreatinginteractivewebexperienceswithitsdynamicnatureandDOMmanipulation.2)Javaoffersstrongtypingandobject-orientedfeatures,idealfor

JavaScript: Exploring Data Types for Efficient Coding JavaScript: Exploring Data Types for Efficient Coding Jun 20, 2025 am 12:46 AM

JavaScripthassevenfundamentaldatatypes:number,string,boolean,undefined,null,object,andsymbol.1)Numbersuseadouble-precisionformat,usefulforwidevaluerangesbutbecautiouswithfloating-pointarithmetic.2)Stringsareimmutable,useefficientconcatenationmethodsf

What is event bubbling and capturing in the DOM? What is event bubbling and capturing in the DOM? Jul 02, 2025 am 01:19 AM

Event capture and bubble are two stages of event propagation in DOM. Capture is from the top layer to the target element, and bubble is from the target element to the top layer. 1. Event capture is implemented by setting the useCapture parameter of addEventListener to true; 2. Event bubble is the default behavior, useCapture is set to false or omitted; 3. Event propagation can be used to prevent event propagation; 4. Event bubbling supports event delegation to improve dynamic content processing efficiency; 5. Capture can be used to intercept events in advance, such as logging or error processing. Understanding these two phases helps to accurately control the timing and how JavaScript responds to user operations.

What's the Difference Between Java and JavaScript? What's the Difference Between Java and JavaScript? Jun 17, 2025 am 09:17 AM

Java and JavaScript are different programming languages. 1.Java is a statically typed and compiled language, suitable for enterprise applications and large systems. 2. JavaScript is a dynamic type and interpreted language, mainly used for web interaction and front-end development.

See all articles