Fiber (fiber) library in Nodejs

Source: Internet
Author: User

fiber/Fiber Drive

In the operating system, in addition to processes and threads, there is a less-applied fiber (fiber, also called co-process). Fibers are often compared to threads, and for the operating system, they are relatively light-weight running states. Fiber turndown threads are generally considered to be lighter and less expensive. The difference is that fiber is created by thread or fiber, fiber scheduling is completely controlled by user code, for the system kernel, is a non-preemptive scheduling mode, fiber to achieve cooperative multi-tasking; threads and processes are subject to kernel scheduling and are prioritized to achieve preemptive multitasking. In addition, the system kernel is not aware of the specific operation of fiber, fiber use is actually relatively independent of the operating system.

In node, a single thread is only for JavaScript, and its underlying is actually full of multithreading. If you need to implement multithreading in JavaScript, a common practice is to write C + + addon, bypassing JavaScript's single-threaded mechanism. However, this approach improves the difficulty and cost of developing debugging. Like many other scripting languages, we can also introduce the concept of fiber into node.

Node-fibers

Node-fibers This library provides a fiber-capable function for node. The multi-threaded aspect did not test the ideal result, but in the asynchronous-to-synchronous role is significant, perhaps in reducing the node call stack, the infinite recursion also has the value to dig. This document mainly describes the use of Node-fibers library and asynchronous to synchronization and other content.

Installation

Node-fibers is written in C language, directly download the source code needs to compile, usually directly NPM installation can:

Copy CodeThe code is as follows:
NPM Install fibers

Use of the Fibers Library

Api

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

Create a fiber that can be used as a constructor or as a normal function call. The following example:

Copy CodeThe 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 assigns a new stack to FN, and FN runs on the new stack until FN has a return value or yields () is called. After FN Returns or calls yield (), the stack resets and when run () is called again, the fiber starts again, and FN runs on the first allocated stack.

2.fiber.current:

Gets the current fiber and can operate on it. If you specify a variable to be associated with it, make sure that the fiber is released, otherwise the V8 garbage collection mechanism ignores this part of memory and causes a memory leak.

3.fiber.yield (param):

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

Copy CodeThe 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" is output and the latter output command is not executed. If a parameter is passed to yield (), then this parameter is used as the return value of the run ().

Copy CodeThe 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 familiar, there is a vague reference to call run () of the two tenses, one is fiber not started when the moment fiber is yield. In both of these tenses, the behavior of Run () is not quite the same.
When fiber is not started, run () takes a parameter and passes it to FN as its argument. When the fiber handles the yielding state, run () takes a parameter and takes it as the return value of yield (), and FN does not run from the beginning, but continues from the point of interruption. For the FN, yield, run three parameters, return values and other relationships, you can use the following small example to illustrate:

Copy CodeThe code is as follows:
var Fiber = require (' fibers ');
var fiber = fiber (function (a) {
Console.log ("First Call to run:");
Console.log ("fn parameter is:" +a);
var B = Fiber.yield ("yield");
Console.log ("Second call to run:");
Console.log ("fn parameter is:" +a);
Console.log ("Yield return value is:" +b);
return "return";
});
Running run for the first time ()
var c=fiber.run ("one");
Running run for the second time ()
var d=fiber.run ("both");
Console.log ("Call Yield,run return:" +c);
Console.log ("FN runs complete, run returns:" +d);

The output is as follows:

Copy CodeThe code is as follows:
/*
Call run for the first time:
The FN parameter is: one
Call run for the second time:
The FN parameter is: one
Yield return value is:
Call Yield,run return: Yield
FN run complete, run returns: Return
*/

From the above example, it is clear that the use of yield is quite different from the syntax of the current JavaScript. In other languages (C #, Python, and so on) The yield keyword has been implemented as an iterator interrupt. You can also implement an iterator on node to see how yield is used. Or take the first Fibonacci sequence as an example:

Copy CodeThe 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 < i++) {
Console.log (F.next ());
}

The output is:

Copy CodeThe code is as follows:
/*
1
1
2
3
5
8
13
21st
34
55
*/

There are two issues to note, first, yield is the method, more like the keyword, unlike run, yield does not need to rely on fiber instances, and run needs. If you call run inside Fiber, be sure to use: Fiber.current.run (); second, yield itself is a reserved keyword for JavaScript and 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 exist in different tenses and affect the behavior of run. The Reset method returns to its original state regardless of what state the fiber handles. Then execute run and the FN will be rerun.

6.fiber.prototype.throwinto (Exception):

Essentially Throwinto throws the exception passed to it, and the exception information is used as the return value of the run. If the exception it throws is not handled within the fiber, the exception continues to bubble. Regardless of whether the exception is handled, it forces yield and interrupts fiber.

Use of the Future library

It is not always reasonable to use fiber directly in node, because the API of fiber is simple, and the actual use inevitably produces repetitive lengthy code that is not conducive to maintenance. It is recommended to add a layer of abstraction between node and fiber, allowing fiber to work better. The future library provides such an abstraction. The future library or any layer of abstraction may not be perfect, and no one is right or wrong, only the application does not apply. For example, the future library provides us with a simple API to perform asynchronous-to-synchronous work, but it does nothing to encapsulate generator (like the Fibonacci sequence generator above).

The future library does not need to download the installation separately, it is already included in the fibers library and only needs Var future=require (' Fibers/future ') when used.

Api

1.function.prototype.future ():

Adds a future method to the function type, transforming the function into a "funture-function".

Copy CodeThe code is as follows:
var futurefun = function Power (a) {
Return a * A;
}.future ();
Console.log (Futurefun (). Wait ());

The power method is actually executed within the Fibel. However, the existing version of the future has a bug, the official no specific instructions, if you need to use this feature, please delete the future.js line No. 339 and No. 350.

2.new Future ()

The constructor of the future object, described in more detail below.

3.future.wrap (FN, IDX)

The Wrap method encapsulates the asynchronous-to-synchronous operation, which is the most valuable method for us in the future library. FN represents the function that needs to be converted, the IDX represents the number of parameters that FN accepts, and considers its callback method to be the last parameter (the API's formulation is controversial, some people tend to pass callback should be in the position, fortunately the Wrap method is relatively simple, it is easier to modify the code). Look at an example to see how wrap is used:

Copy CodeThe 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, it can be seen that fiber asynchronous to synchronization is really effective, in addition to the syntax of a step more. Wait (), other fs.readfilesync methods that have been provided by FS indistinguishable.

4.future.wait (Futures):

This method has been seen many times before. As the name implies, its role is to wait for results. If you want to wait for the result of a future instance, call Futureinstance.wait () directly, or call future.wait (Futuresarray) If you need to wait for the result of a series of future instances. Note that in the second usage, a future instance has an error at run time, and the wait method does not throw an error, but we can use the Get () method to get the running result directly.

5.future.prototype.get ():

The use of Get () is similar to the first way of Wait (), and the difference is that get () returns the result immediately. If the data is not ready, get () throws an error.

6.future.prototype.resolve (PARAM1,PARAM2):

The Wrap method above always gives a future in which the callback function of the Async method is swallowed, and the asynchronous result is returned directly. In fact, the future also provides a solution for setting the callback function through the Resolve method. Resolve accepts up to two parameters, and if only one parameter is passed, the future considers a node-style callback function to be passed, such as the following example:

Copy CodeThe code is as follows:
Futureinstance.resolve (function (err, data) {
if (err) {
throw err;
} else {
Console.log (Data.tostring ());
}
});

If you pass in two parameters, the error and data are processed separately, as shown in the following example:

Copy CodeThe code is as follows:
Futureinstance.resolve (function (err) {
throw err;
}, function (data) {
Console.log (Data.tostring ());
});

In addition, the future does not distinguish between resolve call timing, if the data is not ready, the callback function is pressed into the queue by the resolver () method of the unified dispatch, or directly fetch the data immediately execute the callback function.

7.future.prototype.isresolved ():

Returns a Boolean value that indicates whether the operation has been performed.

8.future.prototype.proxy (futureinstance):

The proxy method provides an agent for the future instance, essentially wrapping the resolve method, in fact, as a callback executor of another instance. For example:

Copy CodeThe code is as follows:
var target = new Future;
Target.resolve (function (err, data) {
Console.log (data)
});
var proxyfun = function (num, CB) {
CB (NULL, num * num);
};
Fiber (function () {
var proxy = Future.wrap (Proxyfun) (10);
Proxy.proxy (target);
}). Run (); Output 100

Although a proxy is executed, the callback function of the final target executes and is the callback function that drives the target with the result of the proxy execution. This kind of proxy means may have a great effect in our practical application, I have not thought deeply in the moment.

9.future.prototype.return (value):

10.future.prototype.throw (Error):

11.future.prototype.resolver ():

12.future.prototype.detach ():

More than four APIs I feel compared to other APIs, the actual use of the scene or function is more general. Return and throw are all subject to resolver method scheduling, these three methods are very important, in the normal future use of the process will silently work, but I did not come up with a specific use of their own scene, so there is no way to specifically introduce. The detach method can only be considered as a simplified version of the Resolve method, nor is it necessary to introduce.

Fiber (fiber) library in Nodejs

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.