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 · 1 revision

refreshexceed会刷新init的缓存;

所有api都能接收参数,参数就是封装的源function的参数;

在下面的所有例子中:

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

我们假设 foo 的执行时间为 50ms;其它时间忽略不计;

OnceInit.init

最常用的api,无论你调用多少次,init都只会执行一次,并返回给你第一次执行(或缓存中)的结果。

async function foo() {
 const res = await axios.get("xxx.com");
 return res;
}
const oiFoo = oi(foo);
await oiFoo.init(); // 50秒后,返回 1
await oiFoo.init(); // 0秒后,返回 1
await oiFoo.init(); // 0秒后,返回 1

如果多个 init 同时执行(第二次调用的时候,第一次执行还没有完成),则第二次及之后的调用将会等待第一次执行的结果,然后返回第一次执行的结果;

setTimeout(oiFoo.init, 30); // 20秒后,执行完毕,返回 1
await oiFoo.init(); // 50秒后,执行完毕,返回 1

OnceInit.refresh

refresh 刷新 once-init 的缓存;如果你在第一次调用 init 之后,希望再执行一次 foo 更新后端数据,你可以执行 refresh

refresh 之后,再执行 oiFoo 将会返回刷新后的数据;

async function foo() {
 const res = await axios.get("xxx.com");
 return res;
}
const oiFoo = oi(foo);
await oiFoo.init(); // 50秒后,返回 1 (无缓存,所以执行)
await oiFoo.refresh(); // 50秒后,返回 2
// refresh 会刷新 init 的缓存
await oiFoo.init(); // 0秒后,返回 2 (已有缓存,所以不会执行)
await oiFoo.refresh(); // 50秒后,返回 3

如果refresh正在刷新,则在refresh结束前执行的init也会refresh结束结束后再返回值,而不会直接返回旧的缓存结果。

多个 refresh 如果在同一时间里同时调用,只会执行一次,并返回第一次执行的结果。【如果你希望同一时间里同时执行,会执行多次,请使用 exceed

setTimeout(oiFoo.refresh, 30); // 20秒后,执行完毕,返回 1
await oiFoo.refresh(); // 50秒后,执行完毕,返回 1

refreshinit 共享一个执行队列,这意味着如果 initrefresh 同时执行,也将只会执行一次并返回第一次执行的结果;

setTimeout(oiFoo.refresh, 30); // 20秒后,执行完毕,返回 1
await oiFoo.init(); // 50秒后,执行完毕,返回 1

OnceInit.get

getinit 的同步版本,相当于获取缓存;如果有缓存的值,那么 get 会返回缓存值;如果没有,则会返回 undefined

oiFoo.get(); // 返回 undefined (从未执行过,所以没有缓存)
await oiFoo.init(); // 50秒后,返回 1
oiFoo.get(); // 返回 1

OnceInit.execute

execute 会直接执行源函数,它既不会修改缓存,也不会插入执行队列。

await oiFoo.init(); // 50秒后,返回 1
await oiFoo.execute(); // 50秒后,返回 2
await oiFoo.init(); // 0秒后,返回 1 (缓存未更新)
await oiFoo.refresh(); // 50秒后,返回 3 (缓存更新,重新获取后端值,由于后端在上次execute请求中虽未更新缓存,但更新了后端,所以返回值为3)

OnceInit.wait

如果当前异步函数正在执行,wait会等待直到结束,如果异步函数没有执行,则立即返回。

wait 没有返回值;

await oiFoo.wait(); // 等待0秒
oiFoo.init();
oiFoo.get(); // 返回 undefined
await oiFoo.wait(); // 等待50秒
oiFoo.get(); // 返回 1

OnceInit.exceed

!!! 这是一个会造成理解困难的函数,请尽量不要和其它 api 混合使用;

exceed 会强制执行函数,无论现在是否正在执行另一个相同的异步函数。

exceed 也会刷新缓存。

refreshinit 的执行受 exceed 影响,但 exceed 的执行不受 refreshinit 的影响;

await Promise.all([oiFoo.exceed(), oiFoo.exceed(), oiFoo.exceed()]); // 50秒后,返回 [1, 2, 3];
// exceed 会刷新缓存
await oiFoo.init(); // 0秒后,返回 3
await oiFoo.refresh(); // 50秒后,返回 4

如果 exceed 正在执行, refreshinit 将会返回 exceed 执行的结果;

注意(WARNING): 如果你不断地执行 exceed ,会导致执行队列不断地刷新,而同一时间执行的 refreshinit 将返回你执行 initrefresh 前最后一次执行exceed的结果。

不推荐你短时间多次调用 exceed ,它可能让你对返回结果造成困扰;大多数情况下,refreshexecute 会是更好的替代品。

请在理解下面这个例子的前提下在实际应用场景中应用 exceed

await Promise.all([oiFoo.refresh(), oiFoo.exceed()]); // 50秒后,返回 [1, 2];
await Promise.all([oiFoo.exceed(), oiFoo.refresh()]); // 50秒后,返回 [3, 3];
await Promise.all([oiFoo.exceed(), oiFoo.refresh(), oiFoo.init()]); // 50秒后,返回 [4, 4, 3];
await oiFoo.init(); // 0秒后,返回 4
await Promise.all([
 oiFoo.exceed(),
 oiFoo.refresh(),
 oiFoo.exceed(),
 oiFoo.refresh(),
 oiFoo.init(),
]); // 50秒后,返回 [5, 5, 6, 6, 4];

Clone this wiki locally

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