纤维的详细的解决方案(咸成)图书馆NodeJS

纤维的详细的解决方案(咸成)图书馆NodeJS
纤维/纤维

操作系统中,有一个小应用纤维(纤维,又称为有限范围),除了进程线程。纤维常与线程相比,和操作系统,他们都是轻量级的操作状态。人们普遍认为,纤维比螺纹更轻、更便宜的。不同的是,纤维的线或纤维,纤维的调度完全由系统内核的用户代码的控制,是一种非抢占式调度方式的光纤实现多任务协作;通过调度线程和进程,按照优先级别,实现抢占式多任务。此外,系统内核并不知道具体的FIB的运行状态呃,光纤的使用与操作系统无关。

在节点,单个线程只是Javascript,和底部全是多线程的。如果你需要实现多线程在Javascript中,常见的做法是写C++插件绕过Javascript单线程机制。然而,这种方法提高了开发和调试的成本和难度。像很多其他的脚本语言,我们也可以将光纤的概念为节点。

结纤维

节点光纤库提供了光纤的节点功能,在多线程中没有理想的结果,但在异步旋转同步中起着重要作用。在减少节点调用堆栈和无限递归方面也有价值,本文主要介绍了节点光纤库的使用方法和异步传输同步。

安装

结纤维是用C语言编写的,直接下载源代码需要被编译,通常直接从安装即可:

复制代码代码如下所示:

新安装的纤维
纤维库的使用

美国石油学会

1纤维(FN)/新纤维(FN):

创建一个可以用作构造函数或正常函数调用的纤维:

复制代码代码如下所示:

函数的Fibo(N){

返回n>1位(n - 1)+ ISPO(n - 2):1;

}

光纤(函数(){())

console.log(ISPO(40));

});
当调用运行()时,光纤路径开始,新的堆栈被分配给FN。FN将在新堆栈上运行,直到FN返回或调用收率()。在FN返回或调用收率()之后,堆栈被重置,当再次调用运行()时,光纤将再次启动,FN在第一个分布式堆栈中运行。

2.fiber.current:

获取当前的纤维并运行它。如果指定一个与之相关的变量,请确保释放光纤路径。否则,V8的垃圾收集机制将忽略这部分内存并导致内存泄漏。

3.fiber.yield(参数):

这个函数在前面的描述中已经提到过。屈服()方法用于中断光纤,在一定程度上类似于返回。一旦执行收率(),该光纤中的后续代码将不会有机会执行,例如:

复制代码代码如下所示:

var纤维=纤维(函数()){

console.log(纤维开始);

fiber.yield();

console.log(纤维停止);

})Run();

输出:光纤 开始
执行后,只输出纤维开始,而后面的输出命令不执行。如果参数被传递给产量(),那么这个参数是运行()的返回值。

复制代码代码如下所示:

var纤维=纤维(函数()){

fiber.yield(成功);

})Run();

console.log(纤维); / / ->成功
4.fiber.prototype.run(参数):

这种方法已经很熟悉了。在前面提到的两种时态之前,有一种说法是,当纤维未被启动时,纤维是屈服的,在这两种时态下,跑步()的行为是不一样的。

当光纤未启动时,运行()接受一个参数,并将其传递给FN作为参数。当光纤处理屈服状态时,运行()接受一个参数,并将其作为收益率()的返回值。FN不会从零开始运行,而是从中断点运行。参数和返回值之间的关系,收益率和运行三可以用下面的小例子来说明:

复制代码代码如下所示:

VaR纤维=需要('fibers);

var光纤=光纤(函数(a){)

console.log(运行:第一叫);

console.log(fn参数是:+);

var b = fiber.yield(屈服);

console.log(跑第二呼叫);

console.log(fn参数是:+);

console.log(收益值是:+ B);

返回返回;

});

第一次运行(运行)

var c = fiber.run();

第二次运行(运行)

var a fiber.run(两);

console.log(叫产量,跑回:+ C);

console.log(FN跑,跑回来:+ D);
输出如下:

复制代码代码如下所示:

*

运行的第一个调用:

FN参数是:一

第二次调用运行:

FN参数是:一

收益率返回值是:两个

呼叫收益率,运行回报率:收益率

FN运行,运行返回:返回

* /
从上面的例子中,很明显,产量从目前使用Javascript语法完全不同。在其他语言(C #,Python等),产量的关键词已经作为迭代器实现。你也可以实现节点的迭代器,看看产量使用。或在斐波那契数列的开端为例:

复制代码代码如下所示:

无功fibogenerator =函数(){()

var a=0,b=0;

当(真){

如果(= = 0){

a = 1;

fiber.yield(一);

{人}

乙=;

b = a = 1:a = b - a;

fiber.yield(B);

}

}

}

var =新纤维(fibogenerator);

f.next = f.run;

对于(var i = 0;i < 10;i + +){

console.log(f.next());

}
输出是:

复制代码代码如下所示:

*













十三

二十一

三十四

五十五

* /
有两个问题需要注意。首先,收益率是一种方法,它更像关键字而不是运行。产量不需要依靠纤维的实例,但运行需要它。如果我们把运行里面的纤维,我们必须使用fiber.current.run();第二,产量本身是Javascript的保留关键字,和不肯定的时候,当它将被启用,所以代码可能会在未来改变。

5.fiber.prototype.reset()():

我们已经知道纤维可能有不同的时态,它也会影响运行的行为。不管是什么状态,重置方法都会返回到初始状态。

6.fiber.prototype.throwinto(例外):

在本质上,throwinto抛出,通过它,使用异常信息作为运行返回值例外。如果异常,将不在纤维处理,除将继续泡沫。无论处理异常或不,它迫使产量和中断纤维。

未来图书馆的使用

由于光纤的API非常简单,在节点中直接使用光纤并不总是合理的。事实上,它将不可避免地产生重复和冗长的代码,这是不利于维护。建议加一层节点和光纤之间的抽象使纤维能更好地工作。未来图书馆提供了这样一个抽象的概念。未来的图书馆或任何抽象层可能不是完美的,没有人是错的任何人,只有适用不适用。例如,未来的图书馆为我们提供了一个简单的API就可以完成异步同步工作,然而它包发生器(类似上述Fibonacci发生器)是无能为力的。

未来的图书馆不需要单独下载和安装,这是已经包含在纤维的图书馆,只有VAR未来=需要('fibers /未来的)使用。

美国石油学会

1.Function.prototype.future () ():

添加本方法的函数式,并转换成一个未来的功能函数。

复制代码代码如下所示:

无功功率futurefun =函数(){

返回一个;

}未来();

console.log(futurefun(10)。等待());
事实上,功率的方法是在不执行。然而,未来现有版本有bug,和官方不指定,如果你需要使用此功能,请删除第三百三十九行和第三百五十行future.js。

2.new未来()

下面将详细描述未来对象的构造函数。

3.future.wrap(FN,IDX)

包装方法封装了异步同步操作,这是未来的library.fn给我们最有价值的方法表示的功能需要转换,要说收到FN的参数数量,回调方法作为最后一个参数(这里的API进行争议,有回调转移倾向应该在的位置,但包的方法比较简单,可以很容易地修改代码)。看一个例子,包装用:

复制代码代码如下所示:

无功readfilesync = future.wrap(要求(FS)。ReadFile);

光纤(函数(){())

VaR的HTML = readfilesync(, / 1。txt)。等ToString()();

console.log(HTML);

})Run();
从这个例子我们可以看到,纤维异步同步确实是非常有效的,除了语法更一步(等),fs.readfilesync方法提供了相同的FS其他。

4.future.wait(期货):

这种方法已经见过多次。顾名思义,它的作用是等待结果。如果你等待未来的一个实例的结果,你可以叫futureinstance.wait()直接;如果你需要等待未来一系列实例结果,叫Future.wait(应该futuresarray)。需要指出的是,在第二使用,未来的情况是在错误的一边跑。等待方法不会抛出错误,但是我们可以使用get()方法直接获取运行结果。

5.future.prototype.get()():

get()的用法类似于等待()的第一种方法,不同的是get()立即返回结果。如果数据没有准备好,get()将抛出错误。

6.future.prototype.resolve(参数,param2):

上述包装方法总是给未来的回调函数,将异步方法直接返回异步的结果。事实上,未来也提供了一个解决方案,通过解决方法设置回调函数。解决接受了两个参数,如果只有一个参数传递,本认为一个节点式的回调函数通过,如下面的例子:

复制代码代码如下所示:

futureinstance.resolve(功能(呃,数据){

如果(错误){

把错误;

{人}

console.log(data.tostring());

}

});
如果引入两个参数,则分别处理错误和数据。示例如下:

复制代码代码如下所示:

futureinstance.resolve(功能(ERR){)

把错误;

函数(数据){ },

console.log(data.tostring());

});
此外,未来不区分决定的通话时间。如果数据没有准备好,回调函数被压缩到队列中,并通过解析器()方法进行统一。否则,数据将直接获取,回调函数立即执行。

7.future.prototype.isresolved()():

返回一个布尔值来指示操作是否已执行。

8.future.prototype.proxy(futureinstance):

代理方法为将来的实例提供了代理,这实质上是解决方法的包装。实际上,它是一个实例的回调方法,比如实例的另一个调用者执行器:

复制代码代码如下所示:

var目标=新未来;

Target.resolve(功能(呃,数据){

console.log(数据)

});

无功proxyfun =功能(num,CB){

CB(空,数字);

};

光纤(函数(){())

代理= future.wrap VaR(proxyfun)(10);

proxy.proxy(目标);

((运行)});输出100
虽然代理被执行,但最终目标的回调函数被执行,目标的回调函数是由代理执行的结果驱动的,这个代理可能对我们的实际应用有很大的影响,我还没有深入考虑。

9.future.prototype.return(价值):

10.future.prototype.throw(错误):

11.future.prototype.resolver()():

12.future.prototype.detach()():

以上四个api我觉得与其他api相比,实际使用的场景还是一般的作用。返回和抛出都是由解析器控制的。这三种方法很重要。它们将在正常的未来应用过程中默默地工作,但我没有想到单独使用它们的具体场景,因此无法详细介绍它们。
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部