Project Icon

IxJS

JavaScript同步异步集合操作库

IxJS为JavaScript提供同步和异步集合操作功能。该库支持可迭代对象、生成器和异步迭代器,统一了拉取式集合的处理方式。IxJS适用于I/O操作,允许按需获取数据。通过Iterable和AsyncIterable类,开发者可使用map、filter、reduce等熟悉方法高效处理各类集合。

JavaScript 交互式扩展(IxJS)

构建状态 构建状态 npm 版本 加入 Gitter 聊天

IxJS 是一组库,用于在 JavaScript 中组合同步和异步集合,以及 Array#extras 风格的组合

JavaScript 交互式扩展(IxJS)将 Array#extras 组合器引入到可迭代对象、生成器、异步可迭代对象和异步生成器中。随着 ES2015 引入 Symbol.iterator 和生成器,以及后续引入 Symbol.asyncIterator 和异步生成器,我们显然需要一个抽象来处理这些数据结构的组合、查询等操作。

IxJS 统一了同步和异步的基于拉取的集合,就像 RxJS 统一了基于推送的集合世界一样。RxJS 非常适合事件驱动的工作流,其中数据可以按生产者的速率推送,而 IxJS 则非常适合 I/O 操作,您作为消费者可以在准备好时拉取数据。

从 npm 安装 IxJS

npm install ix

(另请阅读我们如何打包 IxJS

Iterable

Iterable 类提供了一种创建和组合同步集合的方式,类似于 JavaScript 中的数组、映射和集合,使用您熟悉的 Array#extras 风格方法,如 mapfilterreduce 等。我们可以使用 for ... of 语句来遍历我们的集合。

// ES
import { from } from 'ix/iterable';
import { filter, map } from 'ix/iterable/operators';

// CommonJS
const from = require('ix/iterable').from;
const { filter, map } = require('ix/iterable/operators');

const source = function* () {
  yield 1;
  yield 2;
  yield 3;
  yield 4;
};

const results = from(source()).pipe(
  filter(x => x % 2 === 0),
  map(x => x * x)
);

for (let item of results) {
  console.log(`Next: ${item}`);
}

// Next 4
// Next 16

此外,我们还提供了 forEach 方法,由您选择使用哪一个。

// ES
import { from } from 'ix/asynciterable';
import { filter, map } from 'ix/asynciterable/operators';

// CommonJS
const from = require('ix/asynciterable').from;
const { filter, map } = require('ix/asynciterable/operators');

const source = function* () {
  yield 1;
  yield 2;
  yield 3;
  yield 4;
};

const results = from(source()).pipe(
  filter(x => x % 2 === 0),
  map(x => x * x)
);

results
  .forEach(item => {
    console.log(`Next: ${item}`);
  });
// Next 4
// Next 16

为了打包考虑,我们可以不引入整个 Iterable 库,而是选择我们需要的运算符,直接添加到 Iterable 原型上。

// ES
import { IterableX as Iterable } from 'ix/iterable';
import 'ix/add/iterable/of';
import 'ix/add/iterable-operators/map';

// CommonJS
const { IterableX: Iterable } = require('ix/iterable');
require('ix/add/iterable/of');
require('ix/add/iterable-operators/map');

const results = Iterable.of(1,2,3)
  .map(x => x + '!!');

Iterable 对象通过暴露 [Symbol.iterator] 方法来实现 JavaScript 中的迭代器模式,该方法返回 Iterator 类。迭代器通过调用 next() 方法来产生值,该方法返回 IteratorResult 类。

interface Iterable<T> {
  [Symbol.iterator](): Iterator<T>;
}

interface Iterator<T> {
  next(value?: any): IteratorResult<T>;
  return?(value?: any): IteratorResult<T>;
  throw?(e?: any): IteratorResult<T>;
}

interface IteratorResult<T> {
  value: T;
  done: Boolean;
}

AsyncIterable

AsyncIterable 对象基于 ECMAScript 提案中的异步迭代器。这允许我们创建 Promise 的异步集合,并能够使用我们可以导入的 mapfilterreduce 等方法。与 Iterable 对象类似,我们可以使用 for await ... of 来遍历异步集合。

// ES
import { from } from 'ix/asynciterable';
import { filter, map } from 'ix/asynciterable/operators';

// CommonJS
const from = require('ix/asynciterable').from;
const { filter, map } = require('ix/asynciterable/operators');

const source = async function* () {
  yield 1;
  yield 2;
  yield 3;
  yield 4;
};

const results = from(source()).pipe(
  filter(async x => x % 2 === 0),
  map(async x => x * x)
);

for await (let item of results) {
  console.log(`Next: ${item}`);
}

// Next 4
// Next 16

另外,我们可以使用内置的 forEach 方法,如果有任何错误,可以使用 catch 捕获:

// ES
import { from } from 'ix/asynciterable';
import { filter, map } from 'ix/asynciterable/operators';

// CommonJS
const from = require('ix/asynciterable').from;
const { filter, map } = require('ix/asynciterable/operators');

const source = async function* () {
  yield 1;
  yield 2;
  yield 3;
  yield 4;
};

const results = from(source()).pipe(
  filter(async x => x % 2 === 0),
  map(async x => x * x)
);

results
  .forEach(item => {
    console.log(`Next: ${item}`);
  })
  .catch(err => {
    console.log(`Error ${err}`);
  });

for await (let item of results) {
  console.log(`Next: ${item}`);
}

// Next 4
// Next 16

为了打包考虑,我们可以不引入整个 AsyncIterable 库,而是选择我们需要的运算符,直接添加到 AsyncIterable 原型上。

// ES
import { AsyncIterableX as AsyncIterable } from 'ix/asynciterable';
import 'ix/add/async-iterable/of';
import 'ix/add/asynciterable-operators/map';

// CommonJS
const { AsyncIterableX: AsyncIterable } = require('ix/asynciterable');
require('ix/add/asynciterable-operators/map');

const results = AsyncIterable.of(1,2,3)
  .map(x => x + '!!');

AsyncIterable 类通过暴露 [Symbol.asyncIterator] 方法来实现 JavaScript 中的异步迭代器模式,该方法进而暴露 AsyncIterator 类。迭代器通过调用 next() 方法产生值,该方法返回一个 Promise,解析为 IteratorResult 类。

interface AsyncIterable<T> {
  [Symbol.asyncIterator](): AsyncIterator<T>;
}

interface AsyncIterator<T> {
  [Symbol.asyncIterator](): AsyncIterator<T>;
  next(value?: any): Promise<IteratorResult<T>>;
  return?(value?: any): Promise<IteratorResult<T>>;
  throw?(e?: any): Promise<IteratorResult<T>>;
}

interface IteratorResult<T> {
  value: T;
  done: Boolean;
}

从 Iterable 转换为 AsyncIterable

使用 IxJS,你可以通过多种方法轻松地将 Iterable 转换为 AsyncIterable。首先,我们可以使用 from 函数,既可以作为独立函数使用,也可以在 Ix.AsyncIterable 对象上使用。from 方法接受标准的 IterableGenerator 和 Promise 的 Iterator,甚至是另一个 AsyncIterable

import { from } from 'ix/asynciterable';
import { map } from 'ix/asynciterable/operators';

const xs = [1, 2, 3, 4];
const mapped = from(xs).pipe(
  map(async (item, index) => item * index)
);

for await (let item of mapped) {
  console.log(`Next: ${item}`);
}

// Next 0
// Next 2
// Next 6
// Next 12

贡献

我们感谢对 IxJS 项目的贡献。IxJS 项目的发展得益于像您这样的社区参与。请阅读以下内容,了解如何参与。

行为准则

IxJS 项目有一个严格的行为准则,必须始终遵守。这个行为准则来自贡献者公约。请阅读完整文本,了解哪些行为是允许的,哪些是不允许的。

贡献指南

阅读贡献指南,了解如何参与 IxJS 项目。这包括我们的开发流程以及如何在提交代码之前进行测试。

打包

IxJS 用 TypeScript 编写,但项目被编译为多个 JS 版本和常见的模块格式。为了方便起见,基本的 IxJS 包包含了所有的编译目标,但如果你对 node_modules 的体积很敏感,别担心 —— 我们也考虑到了这一点。这些目标也以 @reactivex 命名空间发布:

npm install @reactivex/ix-ts # TypeScript 目标
npm install @reactivex/ix-es5-cjs # ES5 CommonJS 目标
npm install @reactivex/ix-es5-esm # ES5 ESModules 目标
npm install @reactivex/ix-es5-umd # ES5 UMD 目标
npm install @reactivex/ix-es2015-cjs # ES2015 CommonJS 目标
npm install @reactivex/ix-es2015-esm # ES2015 ESModules 目标
npm install @reactivex/ix-es2015-umd # ES2015 UMD 目标
npm install @reactivex/ix-esnext-cjs # ESNext CommonJS 目标
npm install @reactivex/ix-esnext-esm # ESNext ESModules 目标
npm install @reactivex/ix-esnext-umd # ESNext UMD 目标

我们为什么这样打包

JS 社区是一个多样化的群体,有各种各样的目标环境和工具链。发布多个包可以满足各种类型的项目需求。针对最新 JS 运行时的朋友可以使用 ESNext + ESM 构建。需要广泛浏览器支持和小下载体积的朋友可以使用 UMD 包,它已经通过 Google 的 Closure Compiler 进行了高级优化。

如果你认为我们遗漏了某个编译目标,而这阻碍了你的采用,请开一个 issue。我们随时为你服务 ❤️。

许可证

MIT 许可证 (MIT)

版权所有 (c) ReactiveX

特此免费授予任何获得本软件及相关文档文件("软件")副本的人不受限制地处理本软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,以及允许向其提供软件的人这样做,但须符合以下条件:

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

软件按"原样"提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、特定用途适用性和非侵权性的保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论这些追责来自合同、侵权或其它行为中,还是产生于、源于或有关于本软件以及本软件的使用或其它处置。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号