用 Inngest v4 在本地触发并检查持久任务

用 Inngest v4 在本地触发并检查持久任务

Inngest 官方文档团队(页面未列可确认的个人作者);中文翻译与技术整理:未完纪。

来源:Node.js & TypeScript Quick Start。核对日期:2026-10-09。

应用发送事件到本地Dev Server,process-task执行并保存handle-task结果,再暂停一秒后完成;失败步骤会重试,成功记录可复用。
未完纪原创技术示意图,根据本文机制绘制;不是运行截图。未完纪原创技术示意图

一次HTTP请求返回后,后台任务可能仍在等待、执行或重试。Inngest的持久任务把工作拆成可保存结果的步骤,让流程在暂停或失败后继续。这个本地练习只做一件小事:接收任务事件,保存处理结果,暂停一秒,再在开发界面查看整条执行轨迹。

官方快速入门使用TypeScript SDK v4与Next.js App Router,不需要Inngest账号。v4的 createFunction 是两个参数:配置对象内包含 triggers,第二个参数为处理函数。不要把v3的三参数写法混进来。

准备一个本地Next.js项目

先准备兼容的Node.js与npm,以及启用了App Router、TypeScript和 @/* 别名的Next.js项目。原文通过 create-next-app@latest 建项并使用未固定版本的 npm install inngest。这些命令会获取和执行软件,正式复现应保存所选版本与锁文件;本文未安装任何包。

npx create-next-app@latest --ts --eslint --tailwind --src-dir --app --import-alias='@/*' inngest-guide
cd inngest-guide
npm install inngest

这里保留原文起步命令作为说明,latest不是版本锁定。在已有项目中,先检查是否已经有Inngest客户端与serve路由,避免重复创建。其他框架可以选择官方对应的HTTP适配器,本文后续路径以Next.js为准。

定义客户端与持久函数

在 src/inngest/client.ts 建立客户端,id 用来标识同一个服务中的应用。

import { Inngest } from "inngest";

export const inngest = new Inngest({ id: "my-app" });

在 src/inngest/functions.ts 注册事件处理函数:

import { inngest } from "./client";

export const processTask = inngest.createFunction(
  { id: "process-task", triggers: { event: "app/task.created" } },
  async ({ event, step }) => {
    const result = await step.run("handle-task", () => {
      return { processed: true, id: event.data.id };
    });

    await step.sleep("pause", "1s");
    return { message: `Task ${event.data.id} complete`, result };
  }
);

app/task.created 是触发事件名。step.run("handle-task", ...) 保存成功结果;如果回调抛错,失败步骤可以重试。step.sleep 是流程层面的持久暂停,不需要让原来的用户HTTP请求一直悬着。示例只返回对象,所以不存在真实数据库写入或外部支付。

真实业务需要在事件入口验证 data.id 的类型、长度、格式及调用者对任务的权限。这个示例依赖已知的演示数据,并没有自动获得输入安全保证。

把函数交给HTTP适配器

建立 src/app/api/inngest/route.ts。下例采用项目已配置的 @/ 别名,与原文相对路径导入等价。

import { serve } from "inngest/next";
import { inngest } from "@/inngest/client";
import { processTask } from "@/inngest/functions";

export const { GET, POST, PUT } = serve({
  client: inngest,
  functions: [processTask],
});

只有列入 functions 的函数才通过该路由提供给Inngest。启动应用时,原文在类Unix shell里使用:

INNGEST_DEV=1 npm run dev

PowerShell设置环境变量的语法不同,可在专门的开发终端中使用 $env:INNGEST_DEV = '1' 后再运行开发命令。INNGEST_DEV=1 明确让v4 SDK使用本地Dev Server;它不是生产部署配置。

启动Dev Server,并核对实际端口

npx --ignore-scripts=false inngest-cli@latest dev -u http://localhost:3000/api/inngest

此命令显式允许安装脚本,并选取可变的最新版CLI。执行前需审查来源并固定版本;本文未执行。应用与Dev Server分别保留一个终端。打开本地 http://localhost:8288,在Apps中查找 my-app,在Functions中查找 process-task。如果Next.js实际使用3001或其他端口,-u必须同步修改。

这些只是预期检查点,并非本文已经确认的界面状态。如果看不到函数,应先检查应用路由是否可达、函数是否注册以及端口是否一致,而不是立即重复发送事件。

先手动触发,沿时间线检查

在Functions里选择 process-task,点击Invoke并输入:

{"data":{"id":"task_001"}}

随后在Runs打开这次执行,应能看到 handle-task、一秒暂停及完成结果。按照函数逻辑,预期结构为:

{
  "message": "Task task_001 complete",
  "result": { "processed": true, "id": "task_001" }
}

这是源文给出的期望值,不是此次任务运行得到的输出。Runs应同时用于检查事件内容、每一步输出和执行时间线;只看到一个HTTP成功响应不足以判断任务完成。

从应用发送事件:给演示接口加上边界

原文的 POST /api/create-task 会发送固定的 task_002,没有应用层鉴权。下面是本文的修订版:继续保留固定数据,但仅在开发模式且明确设置本地开关时允许调用,响应使用202表示接受事件。此门禁不是生产鉴权方案,也没有经过运行测试。

import { NextResponse } from "next/server";
import { inngest } from "@/inngest/client";

export async function POST() {
  if (process.env.NODE_ENV !== "development" ||
      process.env.INNGEST_DEV !== "1") {
    return new NextResponse(null, { status: 404 });
  }

  await inngest.send({
    name: "app/task.created",
    data: { id: "task_002" },
  });

  return NextResponse.json({ eventAccepted: true }, { status: 202 });
}

在本地调用此接口后,再去Runs核查 task_002 的最终结果。不要把 eventAccepted 写进用户界面作为“任务完成”。若改为接收外部JSON,应另外加入schema校验、身份验证、任务授权和限流;也不要让本地演示服务直接暴露在不受信任网络上。

curl -X POST http://localhost:3000/api/create-task

有意制造失败,理解重试边界

原文在 handle-task 回调的return之前增加:

if (event.data.id === "retry-demo") {
  throw new Error("Temporary failure");
}

用 {"data":{"id":"retry-demo"}} 手动触发后,预期能在步骤详情看到多次尝试。因为这条分支持续抛错,最终失败才是正确预期;它不是“一次失败后自动成功”的演示。练习结束后移除该分支。

已成功步骤的结果可以复用,但外部副作用未必只发生一次:一个支付或写入请求可能已经成功,却在结果被保存前超时,随后重试再次发出。应给外部写入、支付和消息配置稳定的业务幂等键,并区分临时错误与永久错误。官方错误处理文档进一步提供不可重试错误、补偿、失败处理及重试时间控制;这些需要按业务设计,不能只依赖自动重试。

来源、版本与检查说明

快速入门与错误处理页面于 2026-10-09 核对。文档当前使用 TypeScript SDK v4 API,createFunction 的配置在第一个参数、处理函数在第二个参数;依赖与 CLI 安装命令使用 latest,没有锁定具体包版本。复现时应审查并锁定 SDK、Next.js、Node/Bun/Deno 与 CLI 的兼容组合。

原页面页脚标示 © 2026 Inngest Inc.,未发现针对文档内容的开放转载许可声明。本文翻译及原创图依据另行取得的授权使用;软件 SDK、CLI 和托管服务的许可条款需要分别核对,不能据此推定文档许可。

本文仅对源代码和配置做静态检查,未进行安装、运行或性能测试。文中的期望结果属于原文说明或逻辑推导,不能当作本次实测结果。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容