Skip to content

once / singleFlight

کاری را دقیقاً یک بار انجام می‌دهد و نتیجه را دوباره به کار می‌گیرد: راه‌اندازی تنبل برای تجزیهٔ پیکربندی، محاسبهٔ گران‌بهای یک‌باره، گیرنده‌های تنبل. once همگام است و singleFlight همتای ناهمگامش.

API

once(fn)

پارامترتوضیحنوعپیش‌فرض
fnتابعی که یک بار اجرا می‌شود؛ آنچه تابع نباشد همان‌طور برمی‌گرددFunction | anyالزامی

تابعی پیچیده‌شده برمی‌گرداند. نخستین فراخوانی ارزیابی و انباره می‌کند؛ هر فراخوانی بعدی همان نتیجهٔ نخست را می‌دهد، هر آرگومانی هم که بدهید.

singleFlight(fn)

پارامترتوضیحنوعپیش‌فرض
fnتابع ناهمگامی که یک بار اجرا می‌شود() => Promise<T>الزامی

تابعی پیچیده‌شده به‌همراه اینها برمی‌گرداند:

عضوتوضیحنوع
reset()نتیجهٔ انباره‌شده را دور می‌ریزد تا فراخوانی بعدی دوباره fn را بدواند() => void
startedاینکه نتیجه‌ای دارد یا همین حالا در حال اجراستboolean

memoize(fn)

نام دیگرِ منسوخِ once. هشدار پایین را ببینید.

نمونه

js
import { once, singleFlight } from 'ranuts';

// همگام: پیکربندی تنها در نخستین دسترسی تجزیه می‌شود
const config = once(() => JSON.parse(rawConfig));
config(); // تجزیه می‌کند
config(); // انباره‌شده را می‌دهد

// ناهمگام: پایگاه داده یک بار باز می‌شود، هر چند فراخواننده هم که رقابت کنند
const ready = singleFlight(() => db.openDataBase());
await Promise.all([ready(), ready(), ready()]); // یک بار باز می‌کند

یادداشت‌ها

  1. once بر پایهٔ آرگومان انباره نمی‌کند. تنها آرگومان‌های نخستین فراخوانی اثر دارند. اگر انبارهٔ به‌ازای هر آرگومان می‌خواهید، خودتان Map بگذارید.
  2. once پس از ارزیابی fn را رها می‌کند، پس هر چه آن تابع در چنگ داشت می‌تواند جمع‌آوری شود.
  3. singleFlight ردها را انباره نمی‌کند. تلاش ناکام، انباره را پاک می‌کند تا لغزش گذرای شبکه همچنان تکرارپذیر بماند. انباره کردن یک Promiseِ ردشده، یک تک‌لغزش را جاودانه می‌کرد.
  4. فراخوانندگان هم‌زمانِ singleFlight همان Promiseِ در جریان را شریک می‌شوند، پس fn حتی با رقابت N فراخواننده یک بار می‌دود. این همان پاسخ به آن اشکال کلاسیک است که «init() مقدار void می‌دهد، پس فراخواننده نمی‌تواند منتظرش بماند و نوشتن‌های زودهنگام شکست می‌خورند».

در ۰٫۳ نامش عوض شد

memoize نامی گمراه‌کننده بود: هرگز بر پایهٔ آرگومان انباره نکرد، فقط یک بار می‌دواند. اکنون نام دیگرِ once است و منسوخ شمرده می‌شود. امضای نوع هم پیش‌تر نادرست بود (بی‌آرگومان اعلام شده بود در حالی که آرگومان‌ها را پیش می‌راند)؛ اکنون از روی fn استنتاج می‌شود.

منتشرشده تحت مجوز MIT.