icicleio/icicle

Icicle 是一个 PHP 库,用于使用同步编码技术编写异步代码。

v1.0.0-beta4 2015-09-17 23:05 UTC

README

Icicle 已被弃用,转而使用 Amp v2.0 此版本目前正在开发中,但即将发布。除主 Amp 包、loop 包和 postgres 包外的所有包的 v2.0 分支是 amp_v2,而主 Amp 包、loop 包和 postgres 包的 v2.0 是 master 分支。

Icicle

Icicle 是一个 PHP 库,用于使用同步编码技术编写 异步 代码。

Icicle 使用 协程(由 可等待生成器 构建),以简化异步代码的编写,使用通常用于编写同步代码的技术,例如返回值和抛出异常,而不是使用通常在异步代码中找到的嵌套回调。

Build Status Coverage Status Semantic Version MIT License @icicleio on Twitter

库组件

  • 协程 是可中断的函数,用于使用同步编码模式和错误处理构建异步代码。
  • 可等待 作为异步操作未来值的占位符。可等待可以在协程中生成,以定义中断点。注册到可等待的回调可能返回值和抛出异常。
  • 可观察 代表异步值集,提供通常与集合关联的操作,如 map、filter 和 reduce。可观察也可以在协程中异步迭代。
  • 循环(事件循环) 用于调度函数、运行计时器、处理信号、轮询套接字以获取挂起数据或等待写入空间。

可用包

  • Stream:读取和写入数据的通用基于协程的接口。
  • Socket:异步流套接字服务器和客户端。
  • 并发:提供易于使用的接口,用于使用非阻塞通信和任务执行进行并行执行。
  • DNS:异步 DNS 查询执行器、解析器和连接器。
  • 文件系统:异步文件系统访问。
  • HTTP:异步 HTTP 服务器和客户端。
  • WebSocket:异步 WebSocket 服务器和客户端。
  • React 适配器:将 Icicle 的事件循环和可等待适配到与 React 组件兼容的接口。

文档和支持

要求
  • PHP 5.5+ 用于 v0.9.x 分支(当前稳定)和 v1.x 分支(镜像当前稳定)
  • PHP 7 用于 v2.0(master)分支,支持生成器委派和返回表达式
安装

推荐使用 Composer 包管理器来安装 Icicle。(有关安装和使用 Composer 的信息,请参阅 Composer 安装指南。)

运行以下命令以在您的项目中使用 Icicle:

composer require icicleio/icicle

您还可以手动编辑 composer.json 文件,将 Icicle 添加为项目需求。

// composer.json
{
    "require": {
        "icicleio/icicle": "^0.9"
    }
}
建议
  • pcntl 扩展:启用自定义信号处理。
  • ev 扩展:提供最高性能的事件循环实现。
  • uv 扩展(仅限 PHP 7):另一个提供更高性能事件循环实现的扩展(实验性)。

示例

以下示例脚本演示了如何在 awaitables 中产生 协程 来创建中断点。awaitables 的满足值发送到协程,拒绝异常抛入协程。

#!/usr/bin/env php
<?php

require dirname(__DIR__) . '/vendor/autoload.php';

use Icicle\Awaitable;
use Icicle\Coroutine\Coroutine;
use Icicle\Loop;

$generator = function () {
    try {
        // Sets $start to the value returned by microtime() after approx. 1 second.
        $start = (yield Awaitable\resolve(microtime(true))->delay(1));

        echo "Sleep time: ", microtime(true) - $start, "\n";

        // Throws the exception from the rejected promise into the coroutine.
        yield Awaitable\reject(new Exception('Rejected promise'));
    } catch (Exception $e) { // Catches promise rejection reason.
        echo "Caught exception: ", $e->getMessage(), "\n";
    }

    yield Awaitable\resolve('Coroutine completed');
};

$coroutine = new Coroutine($generator());

$coroutine->done(function ($data) {
    echo $data, "\n";
});

Loop\run();