Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
Xmo edited this page Oct 31, 2022 · 2 revisions
// 0. 引入once-init
import oi from "once-init";
// 1. 创建一个异步函数
async function foo() {
 // do something, for example, request backend data.
 const res = await axios.get("xxx.com");
 return res;
}
// 2. 用once-init封装这个异步函数
const oiFoo = oi(foo);
// 3. 执行封装后的函数
oiFoo.init();

通常来说,axios.get 请求很适合进行封装,你可以用refresh来代替原来的 axios.get 实现无感处理重复请求。

只需要下面这一行:

axios.get = oi(axios.get).refresh;

用例

不用 once-init

// 我们假设 axios.get("xxx.com") 返回的值是一个递增的数字,即第1次请求,会返回1,第2次请求会返回2,第n次请求会返回n。
await foo(); // 返回 1
await foo(); // 返回 2
await foo(); // 返回 3

使用 once-init

// once-init 会将重复执行重定向到第一次执行的结果上;(第一次执行后会缓存执行结果,类似单例模式)
await oiFoo.init(); // 返回 1
await oiFoo.init(); // 返回 1
await oiFoo.init(); // 返回 1

这意味着无论重复执行 oiFoo.init 多少次,foo 都只会执行第一次,返回第一次执行的结果;(就像缓存一样)

await Promise.all([oiFoo.init(), oiFoo.init(), oiFoo.init()]); // 返回 [1, 1, 1]
await Promise.all([oiFoo.init(), oiFoo.init(), oiFoo.init()]); // 返回 [1, 1, 1]
// 通常,如果你只会使用到init,你可以直接把 oiFoo 定义成 init 函数
const oiFoo = oi(foo).init;
await oiFoo();

如果你不使用缓存,只是希望防止同一时间发出重复请求,你可以使用refresh:

// refresh和init在同一时间执行多次,都会阻止重复执行,多余的async function会返回第一次的结果;
await Promise.all([oiFoo.refresh(), oiFoo.refresh(), oiFoo.refresh()]); // 返回 [1, 1, 1]
// 但refresh如果当前没有其它重复的async function在执行,会刷新结果,并同时刷新缓存(影响到下一次init的返回);
await Promise.all([oiFoo.refresh(), oiFoo.refresh(), oiFoo.refresh()]); // 返回 [2, 2, 2]
await oiFoo.init(); // 返回 2

once-init 会区分参数,如果传入的异步函数有参,那么传入不同的参数将被视为两个不同的异步函数,不会共享缓存和执行队列;(使用lodash.isEqual判断参数是否相等)

下面这个复杂用例将会给你提供灵感:

// 假设 xxx.com/+ 会返回正数, xxx.com/- 会返回负数,两者有独立的缓存,且绝对值都递增
async function foo(op: "+" | "-") {
 const res = await axios.get(`xxx.com/${op}`);
 return res;
}
const oiFoo = oi(foo);
await oiFoo.init("-"); // 返回 -1
await oiFoo.refresh("-"); // 返回 -2
await oiFoo.refresh("-"); // 返回 -3
await oiFoo.refresh("+"); // 返回 1
await oiFoo.init("-"); // 返回 -3

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /