search
HomeWeb Front-endJS TutorialDetailed explanation of fiber (fiber) library in nodejs_node.js

fiber/fiber

In the operating system, in addition to processes and threads, there is also a type of fiber (fiber, also called coroutine) that is rarely used. Fibers are often compared with threads. For the operating system, they are both lightweight running states. Fibers are generally considered to be more lightweight and have less overhead than threads. The difference is that fibers are created by threads or fibers, and fiber scheduling is completely controlled by user code. For the system kernel, it is a non-preemptive scheduling method. Fibers realize cooperative multi-tasking. ; Threads and processes are scheduled by the kernel and implement preemptive multitasking according to priority. In addition, the system kernel does not know the specific running status of fibers, and the use of fibers is actually relatively independent of the operating system.

In node, single thread is only for javascript, and its bottom layer is actually full of multi-threads. If you need to implement multi-threading in JavaScript, a common approach is to write a C addon to bypass the single-thread mechanism of JavaScript. However, this method increases the difficulty and cost of development and debugging. Like many other scripting languages, we can also introduce the concept of fibers into node.

node-fibers

The node-fibers library provides fiber functions for node. The multi-threading test has not produced ideal results, but it has a significant effect in converting asynchronous to synchronous, and may also be valuable in reducing node call stacks and infinite recursion. This document mainly introduces how to use the node-fibers library and asynchronous to synchronous conversion.

Install

node-fibers are written in C language. Directly downloading the source code requires compilation. Usually, you can install it directly with npm:

Copy code The code is as follows:

npm install fibers

Usage of fibers library

API

1.Fiber(fn)/ new Fiber(fn):

Create a fiber, which can be used as a constructor or called as an ordinary function. For example:

Copy code The code is as follows:

function fibo(n) {
Return n > 1 ? fibo(n - 1) fibo(n - 2) : 1;
}
Fiber(function () {
console.log(fibo(40));
});

When run() is called, the fiber starts and allocates a new stack for fn. fn will run on this new stack until fn has a return value or yield() is called. After fn returns or calls yield(), the stack is reset. When run() is called again, the fiber will be started again, and fn runs in the stack allocated for the first time.

2.Fiber.current:

Get the current fiber and operate on it. If you specify a variable to be associated with it, be sure to ensure that this fiber can be released, otherwise V8's garbage collection mechanism will always ignore this part of the memory, causing memory leaks.

3.Fiber.yield(param):

This function has been mentioned in the previous description. The yield() method is used to interrupt the fiber, similar to return to a certain extent. Once yield() is executed, subsequent code in this Fiber will have no chance to execute, for example:

Copy code The code is as follows:

var fiber = Fiber(function () {
console.log("Fiber Start");
Fiber.yield();
console.log("Fiber Stop");
}).run();
// Output: "Fiber Start"

After execution, only "Fiber Start" will be output, and the latter output command will not be executed. If a parameter is passed to yield(), then this parameter is used as the return value of run().

Copy code The code is as follows:

var fiber = Fiber(function () {
Fiber.yield("success");
}).run();
console.log(fiber); // -> "success"

4.Fiber.prototype.run(param):

This method is already very familiar. There are two tenses for calling run() mentioned before, one is when the Fiber is not started, and the other is when the Fiber is yielded. The behavior of run() is not the same in these two tenses.
When Fiber is not started, run() accepts an argument and passes it to fn as its argument. When Fiber handles the yielding state, run() accepts a parameter and uses it as the return value of yield(). fn will not run from the beginning, but will continue running from the point of interruption. The relationship between the parameters and return values ​​of fn, yield, and run can be explained through the following small example:

Copy code The code is as follows:

var Fiber = require('fibers');
var fiber = Fiber(function (a) {
console.log("First call run:");
console.log("fn parameter is: " a);
var b = Fiber.yield("yield");
console.log("Second call run:");
console.log("fn parameter is: " a);
console.log("yield return value is: " b);
Return "return";
});
// First run run()
var c=fiber.run("One");
//Run run()
for the second time var d=fiber.run("Two");
console.log("Calling yield, run returns: " c);
console.log("fn operation is completed, run returns: " d);

The output is as follows:

Copy code The code is as follows:

/*
The first time you call run:
The fn parameter is: One
Call run:
for the second time The fn parameter is: One
The return value of yield is: Two
Call yield, run returns: yield
fn is completed and run returns: return
*/

From the above example, it is obvious that the usage of yield is quite different from the current JavaScript syntax. The yield keyword has been implemented in other languages ​​(C#, Python, etc.) as an interrupt for iterators. You might as well implement an iterator on node and experience the use of yield in detail. Let’s take the Fibonacci sequence at the beginning as an example:

Copy code The code is as follows:

var fiboGenerator = function () {
var a = 0, b = 0;
while (true) {
If (a == 0) {
            a = 1;
Fiber.yield(a);
         } else {
              b = a;
                b == a ? a = 1 : a = b - a;
Fiber.yield(b);
}
}
}
var f = new Fiber(fiboGenerator);
f.next = f.run;
for (var i = 0; i console.log(f.next());
}

The output is:

Copy code The code is as follows:

/*
1
1
2
3
5
8
13
21
34
55
*/

There are two issues to pay attention to. First, yield is said to be a method, more like a keyword. Unlike run, yield does not need to rely on a Fiber instance, while run does. If you call run inside Fiber, you must use: Fiber.current.run(); secondly, yield itself is a reserved keyword of JavaScript. It is not sure if and when it will be enabled, so the code may face changes in the future. .

5.Fiber.prototype.reset():

We already know that Fiber may have different tenses, which will also affect the behavior of run. The reset method returns to the initial state no matter what state Fiber processes. Subsequent execution of run will rerun fn.

6.Fiber.prototype.throwInto(Exception):

Essentially, throwInto will throw the exception passed to it and use the exception information as the return value of run. If the exception it throws is not handled in Fiber, the exception will continue to bubble up. Regardless of whether the exception is handled or not, it will force yield and interrupt Fiber.

Usage of future library

It is not always reasonable to use Fiber directly in node, because the API of Fiber is really simple. In actual use, it will inevitably produce repetitive and lengthy code, which is not conducive to maintenance. It is recommended to add a layer of abstraction between node and Fiber to allow Fiber to work better. The future library provides such an abstraction. The future library or any level of abstraction may not be perfect. No one is right or wrong, only what is applicable or not. For example, the future library provides us with a simple API that can complete the work of asynchronous to synchronous, but it cannot do anything to encapsulate the generator (similar to the Fibonacci sequence generator above).

The future library does not need to be downloaded and installed separately. It is already included in the fibers library. When using it, you only need var future=require('fibers/future').

API

1.Function.prototype.future():

Added future method to Function type, converting function into a "funture-function".

Copy code The code is as follows:

var futureFun = function power(a) {
Return a * a;
}.future();
console.log(futureFun(10).wait());

Actually the power method is executed within Fibel. However, the existing version of future has bugs, and there is no official official explanation. If you need to use this function, please delete lines 339 and 350 of future.js.

2.new Future()

Constructor of Future object, detailed below.

3.Future.wrap(fn, idx)

The wrap method encapsulates the asynchronous to synchronous operation and is the most valuable method to us in the future library. fn represents the function that needs to be converted, idx represents the number of parameters accepted by fn, and its callback method is considered to be the last parameter (the formulation of the API here is quite controversial. Some people tend to pass the position where the callback should be. Fortunately, the wrap method is relatively simple and can be It is easier to modify the code). You can understand the usage of wrap by looking at an example:

Copy code The code is as follows:

var readFileSync = Future.wrap(require("fs").readFile);
Fiber(function () {
var html = readFileSync("./1.txt").wait().toString();
console.log(html);
}).run();

From this example, we can see that Fiber asynchronous to synchronous conversion is indeed very effective. Except for the additional step .wait() in the syntax, the other fs.readFileSync methods already provided by fs are the same.

4.Future.wait(futures):

This method has been seen many times before. As the name suggests, its function is to wait for results. If you want to wait for the result of a future instance, just call futureInstance.wait() directly; if you need to wait for the result of a series of future instances, call Future.wait(futuresArray). It should be noted that in the second usage, if an error occurs when a future instance is running, the wait method will not throw an error, but we can use the get() method to directly obtain the running result.

5.Future.prototype.get():

The usage of get() is very similar to the first method of wait(). The difference is that get() returns the result immediately. If the data is not ready, get() will throw an error.

6.Future.prototype.resolve(param1,param2):

The wrap method above always gives people the impression that the future is actually swallowing the callback function of the asynchronous method and directly returns the asynchronous result. In fact, future also provides a solution for setting callback functions through the resolve method. resolve accepts up to two parameters. If only one parameter is passed in, future will think that a node-style callback function is passed, such as the following example:

Copy code The code is as follows:

futureInstance.resolve(함수(err, data) {
만약 (오류) {
           오류를 던집니다.
} 그 밖의 {
console.log(data.toString());
}
});

두 개의 매개변수가 전달되면 오류와 데이터가 별도로 처리된다는 의미입니다.

코드 복사 코드는 다음과 같습니다.

futureInstance.resolve(함수 (err) {
던지기 오류;
}, 함수(데이터) {
console.log(data.toString());
});

또한 future는 Resolve의 호출 시점을 구분하지 않습니다. 데이터가 준비되지 않은 경우 콜백 함수가 대기열에 푸시되고 Resolver() 메서드에 의해 균일하게 예약됩니다. 그렇지 않으면 데이터를 직접 가져옵니다. 콜백 함수가 즉시 실행됩니다.

7.Future.prototype.isResolved():

작업이 수행되었는지 여부를 나타내는 부울 값을 반환합니다.

8.Future.prototype.proxy(futureInstance):

프록시 메소드는 본질적으로 해결 메소드의 래퍼인 미래 인스턴스에 대한 프록시를 제공합니다. 실제로 한 인스턴스의 콜백 메소드를 다른 인스턴스의 콜백 실행자로 사용합니다. 예:

코드 복사 코드는 다음과 같습니다.

var target = 새로운 Future;
target.resolve(함수 (err, data) {
console.log(데이터)
});
var ProxyFun = 함수(숫자, cb) {
cb(null, num * num);
};
섬유(함수 () {
var 프록시 = Future.wrap(proxyFun)(10);
Proxy.proxy(대상);
}).run(); // 100을 출력

프록시가 실행되더라도 결국에는 대상의 콜백 함수가 실행되고, 프록시의 실행 결과에 따라 대상의 콜백 함수가 구동됩니다. 이 프록시 방법은 실제 응용 프로그램에서 큰 역할을 할 수 있지만 아직 깊이 생각해 보지 않았습니다.

9.Future.prototype.return(값):

10.Future.prototype.throw(오류):

11.Future.prototype.resolver():

12.Future.prototype.detach():

위 4가지 API의 경우 다른 API에 비해 실제 사용 시나리오나 기능은 상대적으로 평균적이라고 생각합니다. return과 throw는 모두 리졸버 메서드에 의해 예약됩니다. 이 세 가지 메서드는 매우 중요하며 일반적인 향후 사용 프로세스에서 자동으로 작동합니다. 그러나 별도로 사용하는 구체적인 시나리오를 파악하지 못했기 때문에 소개할 방법이 없습니다. 상세히. Detach 방식은 Resolve 방식의 단순화된 버전으로만 간주할 수 있으므로 도입할 필요는 없습니다.

Statement
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
JavaScript Engines: Comparing ImplementationsJavaScript Engines: Comparing ImplementationsApr 13, 2025 am 12:05 AM

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

Beyond the Browser: JavaScript in the Real WorldBeyond the Browser: JavaScript in the Real WorldApr 12, 2025 am 12:06 AM

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)Apr 11, 2025 am 08:22 AM

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

JavaScript: Exploring the Versatility of a Web LanguageJavaScript: Exploring the Versatility of a Web LanguageApr 11, 2025 am 12:01 AM

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

The Evolution of JavaScript: Current Trends and Future ProspectsThe Evolution of JavaScript: Current Trends and Future ProspectsApr 10, 2025 am 09:33 AM

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

Demystifying JavaScript: What It Does and Why It MattersDemystifying JavaScript: What It Does and Why It MattersApr 09, 2025 am 12:07 AM

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

Is Python or JavaScript better?Is Python or JavaScript better?Apr 06, 2025 am 12:14 AM

Python is more suitable for data science and machine learning, while JavaScript is more suitable for front-end and full-stack development. 1. Python is known for its concise syntax and rich library ecosystem, and is suitable for data analysis and web development. 2. JavaScript is the core of front-end development. Node.js supports server-side programming and is suitable for full-stack development.

See all articles

Hot AI Tools

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.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use