JavaScript多线程运行库Nexus.js详解

首先,如果你不熟悉这个项目,建议先阅读之前写的一系列文章。如果你不想阅读这些,不用担心。这里面也会涉及到那些内容。

现在,让我们开始吧。

去年,我开始实现Nexus.js,这是一个基于Webkit/JavaScript内核的多线程服务端JavaScript运行库。有一段时间我放弃了做这件事,由于一些我无法控制的原因,我不打算在这里讨论,主要是:我无法让自己长时间工作。

所以,让我们从讨论Nexus的架构开始,以及它是如何工作的。

事件循环

没有事件循环

有一个带有(无锁)任务对象的线程池

每次调用setTimeout或setImmediate或创建一个Promise时,任务就排队到任务队列钟。

每当计划任务时,第一个可用的线程将选择任务并执行它。

在CPU内核上处理Promise。对Promise.all()的调用将并行的解决Promise。

ES6

支持async/await,并且推荐使用

支持for await(...)

支持解构

支持async try/catch/finally

模块

不支持CommonJS。(require(...)和module.exports)

所有模块使用ES6的import/export语法

支持动态导入通过import('file-or-packge').then(...)

支持import.meta,例如:import.meta.filename以及import.meta.dirname等等

附加功能:支持直接从URL中导入,例如:

import { h } from 'https://unpkg.com/preact/dist/preact.esm.js';

EventEmitter

Nexus实现了基于Promise的EventEmitter类

事件处理程序在所有线程上排序,并将并行处理执行。

EventEmitter.emit(...)的返回值是一个Promise,它可以被解析为在事件处理器中返回值所构成的数组。

例如:

class EmitterTest extends Nexus.EventEmitter {
 constructor() {
  super();
  for(let i = 0; i < 4; i++)
   this.on('test', value => { console.log(`fired test ${i}!`); console.inspect(value); });
  for(let i = 0; i < 4; i++)
   this.on('returns-a-value', v => `${v + i}`);
 }
}
const test = new EmitterTest();
async function start() {
 await test.emit('test', { payload: 'test 1' });
 console.log('first test done!');
 await test.emit('test', { payload: 'test 2' });
 console.log('second test done!');
 const values = await test.emit('returns-a-value', 10);
 console.log('third test done, returned values are:'); console.inspect(values);
}
start().catch(console.error);

I/O

所有输入/输出都通过三个原语完成:Device,Filter和Stream。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/345.html