纤维/纤维
在
操作系统中,有一个小应用纤维(纤维,又称为有限范围),除了
进程和
线程。纤维常与线程相比,和
操作系统,他们
都是轻量级的操作状态。人们普遍认为,纤维比螺纹更轻、更便宜的。不同的是,纤维的线或纤维,纤维的调度完全由系统内核的
用户代码的
控制,是一种非抢占式调度方式的光纤实现多
任务协作;通过调度线程和进程,按照优先级别,实现抢占式多任务。此外,系统内核并不知道具体的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相比,实际使用的场景还是一般的作用。返回和抛出都是由解析器控制的。这三种方法很重要。它们将在正常的未来应用过程中默默地工作,但我没有想到单独使用它们的具体场景,因此无法详细介绍它们。