When unit testing real-world code, many situations make the test difficult to write. How to check if a function is called? How to test Ajax calls? Or use the code of setTimeout
? At this time, you need to use to test the stand-in - replace the code to make it easier to test within the hard-to-test.
For many years, Sinon.js has been the actual standard for creating test stand-ins in JavaScript testing. It is an essential tool for any JavaScript developer who writes tests, because without it, it is nearly impossible to write tests for real applications.
Recently, a new library called testdouble.js is emerging. It has a similar feature set to Sinon.js, except that there are a few differences here and there.
In this article, we will explore what Sinon.js and testdouble.js provide and compare their respective pros and cons. Is Sinon.js still a better choice, or can the challenger win?
Note: If you are not familiar with testing stand-ins, it is recommended that you read my Sinon.js tutorial first. This will help you better understand the concepts we will discuss here.
Key Points
- Feature Sets and Terminology: Sinon.js provides a traditional set of test stand-ins, including spies, stubs, and mocks, which are familiar to those who are proficient in other programming languages, while testdouble.js simplifies terminology and focuses on it In terms of JavaScript-centric vocabulary, traditional spies are eliminated.
- Easy to use: Testdouble.js has a simpler API that is easier for beginners to master, while Sinon.js provides a more detailed but more complex interface that users familiar with similar test tools in other languages ??may prefer it to others .
- Function of processing input: Sinon.js allows for more flexibility in stubs and assertions to use input parameters without necessarily requiring exact matches, which contrasts with the strict requirement of precise parameter matching by testdouble.js unless explicitly configured.
- Support for Promise and callbacks: Testdouble.js integrates built-in support for Promise and provides powerful callback handling, which may be more suitable for modern JavaScript development than Sinon.js, which requires additional information. Only by configuration can similar functions be achieved.
- Module Replacement Function: Testdouble.js supports replacing the entire module, which is conducive to isolating test module interactions; this function is not available in Sinon.js unless other tools such as proxyquire or rewire are used.
- Cleaning and Maintenance: Testdouble.js simplifies the cleaning process with a single reset function, reducing the risk of remaining test stand-ins that may affect other tests, while Sinon.js provides multiple cleaning methods that can be more troublesome to manage. .
The terms used in this article
To ensure easy understanding of what is being discussed, here is a quick overview of the terms used. These are the definitions of Sinon.js and may vary slightly elsewhere.
- Testing stand-in is a replacement for the functions used during testing. It can refer to any of the three types mentioned below.
- Spy is a test stand-in that allows the effect to be checked without affecting the behavior of the objective function.
- Stub is a test stand-in that replaces the behavior of the objective function with something else, such as the return value.
- Simulation is a different approach than stubs. The simulation contains built-in validation, which can be a substitute for separate assertions.
It should be noted that one of the goals of testdouble.js is to reduce confusion between this term.
Overview of Sinon.js and testdouble.js
Let's first look at the basic usage comparison between Sinon.js and testdouble.js.
Sinon has three different test stand-in concepts: spy, stubs, and mocks. The idea is that each represents a different usage scenario. This makes the library more familiar to people from other languages ??or who have read books using the same terminology, such as xUnit testing mode. But on the other hand, these three concepts may also make Sinon more difficult to understand when first used. This is a basic example of Sinon usage:
// 以下是查看函數(shù)調(diào)用的參數(shù)的方法: var spy = sinon.spy(Math, 'abs'); Math.abs(-10); console.log(spy.firstCall.args); // 輸出:[ -10 ] spy.restore(); // 以下是控制函數(shù)執(zhí)行方式的方法: var stub = sinon.stub(document, 'createElement'); stub.returns('not an html element'); var x = document.createElement('div'); console.log(x); // 輸出:'not an html element' stub.restore();
In contrast, testdouble.js chooses a simpler API. Instead of using concepts like spies or stubs, it uses languages ??that JavaScript developers are more familiar with, such as td.function
, td.object
and td.replace
. This makes testdouble potentially easier to get started and more suitable for certain tasks. But on the other hand, some more advanced uses may simply not be possible (which is sometimes intentional).
The following is how to use testdouble.js:
// 以下是查看函數(shù)調(diào)用的參數(shù)的方法: var abs = td.replace(Math, 'abs'); Math.abs(-10); var explanation = td.explain(abs); console.log(explanation.calls[0].args); // 輸出:[ -10 ] // 以下是控制函數(shù)執(zhí)行方式的方法: var createElement = td.replace(document, 'createElement'); td.when(createElement(td.matchers.anything())).thenReturn('not an html element'); var x = document.createElement('div'); console.log(x); // 輸出:'not an html element' // testdouble 使用一次調(diào)用重置所有測試替身,無需單獨清理 td.reset();
testdouble uses a simpler language. We "replace" the function instead of "stub" it. We require the testdouble "interpretation" function to get information from it. Apart from that, it's quite similar to Sinon so far.
This also extends to creating "anonymous" test stand-in:
var x = sinon.stub();
and
var x = td.function();
Sinon's spies and stubs have attributes that provide more information about them. For example, Sinon provides attributes such as stub.callCount
and stub.args
. In the case of testdouble, we get this information from td.explain
:
// 我們也可以為測試替身命名 var x = td.function('hello'); x('foo', 'bar'); td.explain(x); console.log(x); /* 輸出: { name: 'hello', callCount: 1, calls: [ { args: ['foo', 'bar'], context: undefined } ], description: 'This test double `hello` has 0 stubbings and 1 invocations.\n\nInvocations:\n - called with `("foo", "bar")`.', isTestDouble: true } */
One of the biggest differences is related to how stubs are set and verification is done. With Sinon, you can link commands after the stub and use assertions to verify the result. testdouble.js just show you how you want to call a function—or how to "rehearse" a function call.
var x = sinon.stub(); x.withArgs('hello', 'world').returns(true); var y = sinon.stub(); sinon.assert.calledWith(y, 'foo', 'bar');
and
var x = td.function(); td.when(x('hello', 'world')).thenReturn(true); var y = td.function(); td.verify(y('foo', 'bar'));
This makes the testdouble's API easier to understand, because you don't need to know what actions can be linked at when.
Compare common test tasks in more detail
At a high level, both libraries are quite similar. But what about common testing tasks you might need to perform in a real project? Let's see where some differences begin to appear.
testdouble.js No spy
The first thing to note is that testdouble.js does not have the concept of "spy". While Sinon.js allows us to replace function calls to get information from them while preserving the default behavior of the function, this is simply not possible in testdouble.js. When you replace the function with testdouble, it always loses its default behavior.
But this is not necessarily a problem. The most common usage of spies is to use them to verify that callbacks are called, which is easy to accomplish with td.function
:
var spy = sinon.spy(); myAsyncFunction(spy); sinon.assert.calledOnce(spy);
and
var spy = td.function(); myAsyncFunction(spy); td.verify(spy());
While it's not a big deal, it's still important to note this difference between the two libraries, otherwise you might be surprised if you expect to be able to use spies in testdouble.js in some more specific way.
testdouble.js requires more precise input
The second difference you will encounter is that testdouble is stricter on input.
Sinon's stubs and assertions allow you to be inaccurate with the provided parameters. This is easiest to illustrate by example:
var stub = sinon.stub(); stub.withArgs('hello').returns('foo'); console.log(stub('hello', 'world')); // 輸出:'foo' sinon.assert.calledWith(stub, 'hello'); // 沒有錯誤
and
// 以下是查看函數(shù)調(diào)用的參數(shù)的方法: var spy = sinon.spy(Math, 'abs'); Math.abs(-10); console.log(spy.firstCall.args); // 輸出:[ -10 ] spy.restore(); // 以下是控制函數(shù)執(zhí)行方式的方法: var stub = sinon.stub(document, 'createElement'); stub.returns('not an html element'); var x = document.createElement('div'); console.log(x); // 輸出:'not an html element' stub.restore();
By default, Sinon does not care how many extra parameters are provided to the function. Although it provides functions such as sinon.assert.calledWithExactly
, it is not recommended as the default value in the documentation. Functions like stub.withArgs
also do not have "exactly" variants.
Testdouble.js, on the other hand, requires the specified exact parameters by default. This is by design. The idea is that if the function is provided with some other parameters that are not specified in the test, this may be an error and should fail the test.
Arbitrary parameters can be specified in testdouble.js, but this is not the default value:
// 以下是查看函數(shù)調(diào)用的參數(shù)的方法: var abs = td.replace(Math, 'abs'); Math.abs(-10); var explanation = td.explain(abs); console.log(explanation.calls[0].args); // 輸出:[ -10 ] // 以下是控制函數(shù)執(zhí)行方式的方法: var createElement = td.replace(document, 'createElement'); td.when(createElement(td.matchers.anything())).thenReturn('not an html element'); var x = document.createElement('div'); console.log(x); // 輸出:'not an html element' // testdouble 使用一次調(diào)用重置所有測試替身,無需單獨清理 td.reset();
Use ignoreExtraArgs: true
, the behavior is similar to Sinon.js.
testdouble.js has built-in Promise support
While using Sinon.js's Promise is not complicated, testdouble.js has built-in methods to return and reject Promise.
var x = sinon.stub();
and
var x = td.function();
Note: You can use sinon-as-promised to include similar convenient functions in Sinon 1.x. Sinon 2.0 and newer versions include Promise support in the form of stub.resolves
and stub.rejects
.
The callback support for testdouble.js is more powerful
Sinon and testdouble both provide an easy way to make the stub function callbacks. However, there are some differences in how they work.
Sinon uses stub.yields
to make the stub call the first function received as a parameter.
// 我們也可以為測試替身命名 var x = td.function('hello'); x('foo', 'bar'); td.explain(x); console.log(x); /* 輸出: { name: 'hello', callCount: 1, calls: [ { args: ['foo', 'bar'], context: undefined } ], description: 'This test double `hello` has 0 stubbings and 1 invocations.\n\nInvocations:\n - called with `("foo", "bar")`.', isTestDouble: true } */testdouble.js defaults to Node style mode, where the callback is assumed to be the
last parameter. You don't have to specify it when rehearsing the call:
var x = sinon.stub(); x.withArgs('hello', 'world').returns(true); var y = sinon.stub(); sinon.assert.calledWith(y, 'foo', 'bar');What makes the callback support of testdouble more powerful is that you can easily define the behavior of scenarios with multiple callbacks or different orders of callbacks.
Suppose we want to call
…callback1
var x = td.function(); td.when(x('hello', 'world')).thenReturn(true); var y = td.function(); td.verify(y('foo', 'bar'));Note that we pass
as a parameter to the function in td.callback
. This tells testdouble which parameter we want to use as the callback. td.when
var spy = sinon.spy(); myAsyncFunction(spy); sinon.assert.calledOnce(spy);In this case, we use
instead of callsArgWith
. We have to provide a specific index of the call to make it work, which can be a bit cumbersome, especially on functions with many parameters. yields
two callbacks with certain values?
var spy = td.function(); myAsyncFunction(spy); td.verify(spy());With Sinon, this is simply impossible. You can link multiple calls to
, but it will only call one of them. callsArgWith
In addition to being able to replace functions with
, testdouble also allows you to replace the entire module. td.replace
var stub = sinon.stub(); stub.withArgs('hello').returns('foo'); console.log(stub('hello', 'world')); // 輸出:'foo' sinon.assert.calledWith(stub, 'hello'); // 沒有錯誤If we want to replace it with testdouble, we can use
, for example...td.replace('path/to/file')
// 以下是查看函數(shù)調(diào)用的參數(shù)的方法: var spy = sinon.spy(Math, 'abs'); Math.abs(-10); console.log(spy.firstCall.args); // 輸出:[ -10 ] spy.restore(); // 以下是控制函數(shù)執(zhí)行方式的方法: var stub = sinon.stub(document, 'createElement'); stub.returns('not an html element'); var x = document.createElement('div'); console.log(x); // 輸出:'not an html element' stub.restore();
Although Sinon.js can replace member functions of an object, it cannot replace modules like this. To do this when using Sinon, you need to use another module, such as proxyquire or rewire.
// 以下是查看函數(shù)調(diào)用的參數(shù)的方法: var abs = td.replace(Math, 'abs'); Math.abs(-10); var explanation = td.explain(abs); console.log(explanation.calls[0].args); // 輸出:[ -10 ] // 以下是控制函數(shù)執(zhí)行方式的方法: var createElement = td.replace(document, 'createElement'); td.when(createElement(td.matchers.anything())).thenReturn('not an html element'); var x = document.createElement('div'); console.log(x); // 輸出:'not an html element' // testdouble 使用一次調(diào)用重置所有測試替身,無需單獨清理 td.reset();
Another thing you need to note about module replacement is that testdouble.js will automatically replace the entire module. If it is a function export like the example here, it replaces the function. If it is an object containing multiple functions, it replaces all of them. Constructors and ES6 classes are also supported. Both proxyquire and rewire require that you specify individually what and how to replace.
testdouble.js missing some helper functions for Sinon
If you use Sinon's emulation timer, emulation XMLHttpRequest, or emulation server, you will notice that they do not exist in the testdouble.
The emulation timer can be used as a plugin, but the XMLHttpRequests and Ajax functions need to be handled in different ways.
A simple solution is to replace the Ajax function you are using, e.g. $.post
:
var x = sinon.stub();
It is easier to clean up test content using testdouble.js
A common stumbling block for beginners in Sinon.js is often clean up spies and stubs. Sinon offers three different ways to do this, which doesn't help much.
var x = td.function();or:
// 我們也可以為測試替身命名 var x = td.function('hello'); x('foo', 'bar'); td.explain(x); console.log(x); /* 輸出: { name: 'hello', callCount: 1, calls: [ { args: ['foo', 'bar'], context: undefined } ], description: 'This test double `hello` has 0 stubbings and 1 invocations.\n\nInvocations:\n - called with `("foo", "bar")`.', isTestDouble: true } */or:
var x = sinon.stub(); x.withArgs('hello', 'world').returns(true); var y = sinon.stub(); sinon.assert.calledWith(y, 'foo', 'bar');Usually, it is recommended to use sandbox and
methods, otherwise it is easy to accidentally leave stubs or spies, which may cause problems with other tests. This can lead to hard-to-trace cascade failures. sinon.test
. The recommended method is to call it in the td.reset()
hook: afterEach
var x = td.function(); td.when(x('hello', 'world')).thenReturn(true); var y = td.function(); td.verify(y('foo', 'bar'));This greatly simplifies the setup of the test stand-in and clean up after testing, reducing the possibility of difficult-to-track errors.
Pros and cons
We have now understood the functionality of these two libraries. They both offer a fairly similar set of features, but they have different design ideas from each other. Can we break it down into advantages and disadvantages?
Let's talk about Sinon.js first. It provides some more additional features than testdouble.js and some aspects of it are easier to configure. This provides some higher flexibility for it in more special testing scenarios. Sinon.js also uses the language of people who are more familiar with other languages—concepts such as spies, stubs and mocks exist in different libraries and has also been discussed in test-related books.
The disadvantage is that it increases complexity. While its flexibility allows experts to do more things, it means that certain tasks are more complex than in testdouble.js. It may also have a steeper learning curve for those new to test the concept of a stand-in. In fact, even someone as familiar with it as me may have a hard time explaining in detail some of the differences between
and sinon.stub
! sinon.mock
testdouble.js selected a simpler interface. Most of its content is fairly simple and easy to use and feels better suited to JavaScript, while Sinon.js sometimes feels like it's designed for other languages. Thanks to this and some of the design principles, it is easier for beginners to get started, and even experienced testers will find many tasks easier to complete. For example, testdouble uses the same API to set up test stand-ins and verify results. It may also be less prone to errors due to its simpler cleaning mechanism.
testdouble The biggest problem is caused by some of its design principles. For example, a complete lack of spies may make it impossible for some people who prefer to use spies over stubs. This is largely a question of opinion and you may not find the problem at all. Besides that, although testdouble.js is an updated library, it is providing some serious competition for Sinon.js.
Compare by function
The following is a comparison by function:
功能 | Sinon.js | testdouble.js |
---|---|---|
間諜 | 是 | 否 |
存根 | 是 | 是 |
延遲存根結(jié)果 | 否 | 是 |
模擬 | 是 | 是1 |
Promise 支持 | 是(在 2.0 中) | 是 |
時間輔助函數(shù) | 是 | 是(通過插件) |
Ajax 輔助函數(shù) | 是 | 否(改為替換函數(shù)) |
模塊替換 | 否 | 是 |
內(nèi)置斷言 | 是 | 是 |
匹配器 | 是 | 是 |
自定義匹配器 | 是 | 是 |
參數(shù)捕獲器 | 否2 | 是 |
代理測試替身 | 否 | 是 |
- testdouble.js Technically speaking There is no simulation like that in Sinon.js. However, since the simulation in Sinon is essentially an object that contains stubs and validation, similar effects can be achieved by using
td.replace(someObject)
. - can be achieved similar effects as parameter capturers by using
stub.yield
(not to be confused withstub.yields
).
Summary and Conclusion
Sinon.js and testdouble.js both provide a fairly similar set of features. In this regard, neither is obviously superior.
The biggest difference between the two is their API. Sinon.js is probably a little bit longer and offers many options on how to do things. This may be its pros and cons. testdouble.js has a leaner API, which makes it easier to learn and use, but due to its more arbitrary design, some may find it problematic.
So which one is suitable for me?
Do you agree with the design principles of testdouble? If so, then there is no reason not to use it. I've used Sinon.js in many projects and I can safely say that testdouble.js does at least 95% of the work I've done in Sinon.js and the remaining 5% may be done with some simple workaround.
If you find Sinon.js difficult to use, or are looking for a more "JavaScript-style" testdouble.js might be for you as well. Even people like me who spend a lot of time learning to use Sinon, I tend to suggest trying testdouble.js and see if you like it.
However, some aspects of testdouble.js may cause headaches for those with knowledge of Sinon.js or other experienced testers. For example, the complete lack of spies may be the decisive factor. Sinon.js is still a good choice for experts and those who want the most flexibility.
If you want to learn more about how to use test stand-ins in practice, check out my free Sinon.js guide. While it uses Sinon.js, you can also apply the same techniques and best practices to testdouble.js.
Are there any problems? Comment? Are you already using testdouble.js? After reading this article, would you consider giving it a try? Please let me know in the comments below.
This article was reviewed by James Wright, Joan Yin, Christian Johansen and Justin Searls. Thanks to all SitePoint peer reviewers for getting SitePoint content to its best!
Frequently Asked Questions about JavaScript Test Tools: Sinon.js vs. Testdouble.js
What is the main difference between Sinon.js and Testdouble.js?
Sinon.js and Testdouble.js are both popular JavaScript test libraries, but they have some key differences. Sinon.js is known for its rich feature set, including spies, stubs, and simulations, as well as utilities for emulating timers and XHR. It is a versatile tool that can be used in conjunction with any testing framework. On the other hand, Testdouble.js is a minimalist library that focuses on providing a simple and intuitive API for testing stand-ins, which are alternatives to the parts of the system to be tested. It does not include utilities for emulating timers or XHRs, but it is designed to be easy to use and understand, so it is a great option for those who prefer a leaner method of testing.
How to install Sinon.js and Testdouble.js?
Sinon.js and Testdouble.js can be installed through npm (Node.js package manager). For Sinon.js, you can use the command npm install sinon
. For Testdouble.js, the command is npm install testdouble
. After installation, you can use const sinon = require('sinon')
and const td = require('testdouble')
to introduce them in your test files, respectively.
Can I use Sinon.js and Testdouble.js at the same time?
Yes, Sinon.js and Testdouble.js can be used simultaneously in the same project. They are all designed to be very neatly simple and work well with other libraries. However, remember that they have overlapping features, so using them at the same time can lead to confusion. It is usually recommended to choose one of them based on your specific needs and preferences.
How to create a spy using Sinon.js and Testdouble.js?
In Sinon.js, you can use sinon.spy()
to create spies. This function returns a spy object that records all calls made to it, including parameters, return values, and exceptions. In Testdouble.js, you can create spies using td.function()
. This function returns a test stand-alone function that records all calls, including parameters.
How to create stubs using Sinon.js and Testdouble.js?
In Sinon.js, you can create stubs using sinon.stub()
. This function returns a stub object that behaves like a spy, but it also allows you to define its behavior, such as specifying a return value or throwing an exception. In Testdouble.js, you can create stubs using td.when()
. This function allows you to define your behavior when calling a test standby with a specific parameter.
How to use Sinon.js and Testdouble.js to verify spies or stubs?
In Sinon.js, you can use methods such as spy.called
, spy.calledWith()
, and spy.returned()
to verify spies or stubs. In Testdouble.js, you can use td.verify()
to assert whether the test standby is called in some way.
What are the advantages of using Sinon.js instead of Testdouble.js?
Sinon.js has a more comprehensive feature set compared to Testdouble.js. It includes utilities for emulating timers and XHR, which is very useful for testing certain types of code. It is also used more widely and has a larger community, which means more resources and support can be obtained.
What are the advantages of using Testdouble.js instead of Sinon.js?
Testdouble.js has a simpler and more intuitive API than Sinon.js. It is designed to be easy to use and understand, so it is a great choice for those who prefer a more streamlined test method. It also encourages good testing practices by making it difficult to abuse test stand-ins.
Can I use Sinon.js and Testdouble.js with other test frameworks?
Yes, Sinon.js and Testdouble.js are both designed very neatly and work well with other test frameworks. They can be used with any JavaScript-enabled test framework.
What resources are there to learn more about Sinon.js and Testdouble.js?
Yes, Sinon.js and Testdouble.js have a lot of documentation on their official websites. There are also many tutorials, blog posts, and online courses covering in-depth content from these libraries.
The above is the detailed content of JavaScript Testing Tool Showdown: Sinon.js vs testdouble.js. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

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

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

There are three common ways to initiate HTTP requests in Node.js: use built-in modules, axios, and node-fetch. 1. Use the built-in http/https module without dependencies, which is suitable for basic scenarios, but requires manual processing of data stitching and error monitoring, such as using https.get() to obtain data or send POST requests through .write(); 2.axios is a third-party library based on Promise. It has concise syntax and powerful functions, supports async/await, automatic JSON conversion, interceptor, etc. It is recommended to simplify asynchronous request operations; 3.node-fetch provides a style similar to browser fetch, based on Promise and simple syntax

JavaScript data types are divided into primitive types and reference types. Primitive types include string, number, boolean, null, undefined, and symbol. The values are immutable and copies are copied when assigning values, so they do not affect each other; reference types such as objects, arrays and functions store memory addresses, and variables pointing to the same object will affect each other. Typeof and instanceof can be used to determine types, but pay attention to the historical issues of typeofnull. Understanding these two types of differences can help write more stable and reliable code.

Which JavaScript framework is the best choice? The answer is to choose the most suitable one according to your needs. 1.React is flexible and free, suitable for medium and large projects that require high customization and team architecture capabilities; 2. Angular provides complete solutions, suitable for enterprise-level applications and long-term maintenance; 3. Vue is easy to use, suitable for small and medium-sized projects or rapid development. In addition, whether there is an existing technology stack, team size, project life cycle and whether SSR is needed are also important factors in choosing a framework. In short, there is no absolutely the best framework, the best choice is the one that suits your needs.

Hello, JavaScript developers! Welcome to this week's JavaScript news! This week we will focus on: Oracle's trademark dispute with Deno, new JavaScript time objects are supported by browsers, Google Chrome updates, and some powerful developer tools. Let's get started! Oracle's trademark dispute with Deno Oracle's attempt to register a "JavaScript" trademark has caused controversy. Ryan Dahl, the creator of Node.js and Deno, has filed a petition to cancel the trademark, and he believes that JavaScript is an open standard and should not be used by Oracle

CacheAPI is a tool provided by the browser to cache network requests, which is often used in conjunction with ServiceWorker to improve website performance and offline experience. 1. It allows developers to manually store resources such as scripts, style sheets, pictures, etc.; 2. It can match cache responses according to requests; 3. It supports deleting specific caches or clearing the entire cache; 4. It can implement cache priority or network priority strategies through ServiceWorker listening to fetch events; 5. It is often used for offline support, speed up repeated access speed, preloading key resources and background update content; 6. When using it, you need to pay attention to cache version control, storage restrictions and the difference from HTTP caching mechanism.

Promise is the core mechanism for handling asynchronous operations in JavaScript. Understanding chain calls, error handling and combiners is the key to mastering their applications. 1. The chain call returns a new Promise through .then() to realize asynchronous process concatenation. Each .then() receives the previous result and can return a value or a Promise; 2. Error handling should use .catch() to catch exceptions to avoid silent failures, and can return the default value in catch to continue the process; 3. Combinators such as Promise.all() (successfully successful only after all success), Promise.race() (the first completion is returned) and Promise.allSettled() (waiting for all completions)

JavaScript array built-in methods such as .map(), .filter() and .reduce() can simplify data processing; 1) .map() is used to convert elements one to one to generate new arrays; 2) .filter() is used to filter elements by condition; 3) .reduce() is used to aggregate data as a single value; misuse should be avoided when used, resulting in side effects or performance problems.

JavaScript's event loop manages asynchronous operations by coordinating call stacks, WebAPIs, and task queues. 1. The call stack executes synchronous code, and when encountering asynchronous tasks, it is handed over to WebAPI for processing; 2. After the WebAPI completes the task in the background, it puts the callback into the corresponding queue (macro task or micro task); 3. The event loop checks whether the call stack is empty. If it is empty, the callback is taken out from the queue and pushed into the call stack for execution; 4. Micro tasks (such as Promise.then) take precedence over macro tasks (such as setTimeout); 5. Understanding the event loop helps to avoid blocking the main thread and optimize the code execution order.
