Skip to main content

函数

🌐 Functions

Page summary:

src/index 托管全局注册、引导和销毁函数,以在应用生命周期中运行逻辑。

./src/index.js 文件(或在 基于 TypeScript 的项目中为 ./src/index.ts 文件)包含全局的 registerbootstrapdestroy 函数,可用于添加动态和基于逻辑的配置。

🌐 The ./src/index.js file (or ./src/index.ts file in a TypeScript-based project) includes global register, bootstrap and destroy functions that can be used to add dynamic and logic-based configurations.

这些函数可以是同步的、异步的或返回一个 promise。

🌐 The functions can be synchronous, asynchronous, or return a promise.

Loading diagram...

可用模式

🌐 Available modes

生命周期函数支持三种执行模式,因此你可以将它们与它们管理的依赖对齐。Strapi 会等待每个函数完成,无论它是正常返回、解析一个 async 函数,还是解析一个 Promise,然后才继续启动或关闭过程。

🌐 Lifecycle functions support 3 execution patterns/modes so you can align them with the dependencies they manage. Strapi waits for each function to finish, whether it returns normally, resolves an async function, or resolves a promise, before moving on with startup or shutdown.

Strapi 不使用返回值,因此函数应仅在设置或清理完成后才解析(或返回),并在失败时抛出异常或拒绝。

🌐 Return values aren't used by Strapi, so the functions should resolve (or return) only when their setup or cleanup is complete and throw or reject to signal a failure.

同步

🌐 Synchronous

同步函数运行的逻辑会立即完成,无需等待其他异步任务。

🌐 Synchronous functions run logic that completes immediately without awaiting other asynchronous tasks.

module.exports = {
register({ strapi }) {
strapi.log.info('Registering static configuration');
},
bootstrap({ strapi }) {
strapi.log.info('Bootstrap finished without awaiting tasks');
},
destroy({ strapi }) {
strapi.log.info('Server shutdown started');
}
};

异步

🌐 Asynchronous

异步函数使用 async 关键字来 await 任务,例如 API 调用或数据库查询,然后 Strapi 才继续。

🌐 Asynchronous functions use the async keyword to await tasks such as API calls or database queries before Strapi continues.

module.exports = {
async register({ strapi }) {
await new Promise((resolve) => setTimeout(resolve, 200));
strapi.log.info('Async register finished after a short delay');
},
async bootstrap({ strapi }) {
const { results: articles } = await strapi
.documents('api::article.article')
.findMany({
filters: { publishedAt: { $notNull: true } },
fields: ['id'],
});
strapi.log.info(`Indexed ${articles.length} published articles`);
},
async destroy({ strapi }) {
await strapi.documents('api::temporary-cache.temporary-cache').deleteMany({
filters: {},
});
}
};

返回一个承诺

🌐 Returning a promise

返回 Promise 的函数会返回一个 Promise,以便 Strapi 可以等待其解析后再继续执行。

🌐 Promise-returning functions hand back a promise so Strapi can wait for its resolution before continuing.

module.exports = {
register({ strapi }) {
return new Promise((resolve) => {
strapi.log.info('Registering with a delayed startup task');
setTimeout(resolve, 200);
});
},
bootstrap({ strapi }) {
return new Promise((resolve, reject) => {
strapi
.documents('api::category.category')
.findMany({ filters: { slug: 'general' }, pageSize: 1 })
.then(({ results }) => {
if (results.length === 0) {
return strapi.documents('api::category.category').create({
data: { name: 'General', slug: 'general' },
});
}

return results[0];
})
.then(() => {
strapi.log.info('Ensured default category exists');
resolve();
})
.catch(reject);
});
},
destroy({ strapi }) {
return new Promise((resolve, reject) => {
strapi
.documents('api::temporary-cache.temporary-cache')
.deleteMany({ filters: {} })
.then(() => {
strapi.log.info('Cleared temporary cache before shutdown');
resolve();
})
.catch(reject);
});
}
};

生命周期函数

🌐 Lifecycle functions

生命周期函数允许你在 Strapi 启动和关闭的特定阶段放置代码。

🌐 Lifecycle functions let you place code at specific phases of Strapi's startup and shutdown.

  • register() 函数用于服务启动前的配置时设置。
  • bootstrap() 函数用于需要 Strapi API 的初始化。
  • destroy() 函数用于在应用停止时进行清理。

注册

🌐 Register

register 生命周期函数,位于 ./src/index.js(或在 ./src/index.ts 中),是一个在应用初始化之前运行的异步函数。

🌐 The register lifecycle function, found in ./src/index.js (or in ./src/index.ts), is an asynchronous function that runs before the application is initialized.

register() 是 Strapi 应用启动时发生的第一件事。这发生在任何设置过程之前,并且在 register() 函数中你无法访问数据库、路由、策略或任何其他后端服务器元素。

register() 函数可以用于:

🌐 The register() function can be used to:

更具体地说,register() 的典型用例包括前置安全任务,例如在应用完成初始化之前加载密钥、轮换 API 密钥或注册认证提供者。

🌐 More specifically, typical use-cases for register() include front-load security tasks such as loading secrets, rotating API keys, or registering authentication providers before the app finishes initializing.

module.exports = {
register({ strapi }) {
strapi.customFields.register({
name: 'color',
plugin: 'my-color-picker',
type: 'string',
});
},
};

自举

🌐 Bootstrap

bootstrap 生命周期函数,位于 ./src/index.js(或 ./src/index.ts 中),在每次服务器启动时都会被调用。

🌐 The bootstrap lifecycle function, found in ./src/index.js (or in ./src/index.ts), is called at every server start.

bootstrap() 会在后端服务器启动之前但在 Strapi 应用设置之后运行,因此你可以访问 strapi 对象中的任何内容。

bootstrap 函数可以用于:

🌐 The bootstrap function can be used to:

更具体地说,bootstrap() 的典型用例是支持编辑工作流程。例如,通过提供初始内容、附加 webhook,或在启动时安排 cron 作业。

🌐 More specifically, a typical use-case for bootstrap() is supporting editorial workflows. For example by seeding starter content, attaching webhooks, or scheduling cron jobs at startup.

Tip

你可以在终端中运行 yarn strapi console(或 npm run strapi console)并与 strapi 对象进行交互。

🌐 You can run yarn strapi console (or npm run strapi console) in the terminal and interact with the strapi object.

module.exports = {
async bootstrap({ strapi }) {
const { results } = await strapi
.documents('api::category.category')
.findMany({ filters: { slug: 'general' }, pageSize: 1 });

if (results.length === 0) {
await strapi.documents('api::category.category').create({
data: { name: 'General', slug: 'general' },
});
strapi.log.info('Created default category');
}
},
};

摧毁

🌐 Destroy

./src/index.js(或./src/index.ts)中的destroy函数是一个异步函数,会在应用关闭之前运行。

🌐 The destroy function, found in ./src/index.js (or in ./src/index.ts), is an asynchronous function that runs before the application gets shut down.

destroy 函数可用于优雅地:

🌐 The destroy function can be used to gracefully:

更具体地说,destroy() 的一个典型用例是处理操作清理,例如关闭数据库或队列连接以及移除监听器,以便应用能够干净地关闭。

🌐 More specifically, a typical use-case for destroy() is to handle operational clean-up, such as closing database or queue connections and removing listeners so the application can shut down cleanly.

let heartbeat;

module.exports = {
async bootstrap({ strapi }) {
heartbeat = setInterval(() => {
strapi.log.debug('Heartbeat interval running');
}, 60_000);
},

async destroy() {
clearInterval(heartbeat);
},
};

使用

🌐 Usage


组合使用

🌐 Combined usage

所有 3 个生命周期函数可以组合使用,以配置应用启动和关闭期间的自定义行为。

🌐 All 3 lifecycle functions can be put together to configure custom behavior during application startup and shutdown.

  1. 确定逻辑的运行时间。
    • register() 中添加仅初始化任务(例如,注册自定义字段或提供程序)。
    • bootstrap() 中添加需要完整 Strapi 访问权限的启动任务(例如,播种或附加网页钩子)。
    • destroy() 中添加清理逻辑(例如关闭外部连接)。
  2. 将代码放入 src/index.js|ts。保持 register() 精简,因为它在 Strapi 完全设置之前运行。
  3. 重启 Strapi 以确认每个生命周期按顺序执行。
src/index.ts
let cronJobKey: string | undefined;

export default {
register({ strapi }) {
strapi.customFields.register({
name: 'color',
type: 'string',
plugin: 'color-picker',
});
},

async bootstrap({ strapi }) {
cronJobKey = 'log-reminders';

strapi.cron.add({
[cronJobKey]: {
rule: '0 */6 * * *', // every 6 hours
job: async () => {
strapi.log.info('Remember to review new content in the admin panel.');
},
},
});
},

async destroy({ strapi }) {
if (cronJobKey) {
strapi.cron.remove(cronJobKey);
}
},
};
Additional information

你可能会在 this blog article 中找到关于注册生命周期函数的更多信息。