Skip to content

mxydl2009/promise-extra

Repository files navigation

Description

this package is aimed at providing extra promise related methods to simplify the code.

Usage

limit method

example

const { limit } = require("@mxydl2009/promise-extra"); // commonjs module

import { limit } from "@mxydl2009/promise-extra"; // es module

// async task factory
function taskFactory(name, interval) {
  return new Promise(function (resolve) {
    console.log(`task ${name} has started!`);
    setTimeout(() => {
      console.log("~~~~~~~~~", `task ${name} has finished!`);
      resolve(`task-${name}`);
    }, interval);
  });
}

const taskIntervals = [];
for (let index = 0; index < 8; index++) {
  const interval = Math.floor(Math.random() * 1800);
  taskIntervals.push({
    name: `${interval}`,
    interval,
  });
}
// constrain the concurrency to 3
const limited = limit(3);
// register the async tasks
taskIntervals.forEach((item) =>
  limited(() => taskFactory(item.name, item.interval))
);
// start the registered async tasks
limited.run().then((res) => {
  console.log("result", res); // res: [task-xxx, task-xxx, ...]
});

last method

example

const { last } = require("@mxydl2009/promise-extra"); // commonjs module

import { last } from "@mxydl2009/promise-extra"; // es module
// define async task function
function asyncTask(name, interval) {
  var text = `task-${name}`;
  return new Promise(function (resolve) {
    setTimeout(() => {
      resolve(text);
    }, interval || 1000);
  });
}
let result = null;
let index = 0;

// define the original event handler
function handler(event) {
  console.log("event", event); // original event object
  const name = index++;
  // interval should be random when async task is a web request
  const interval = 500;
  return asyncTask(name, interval);
}

// wrap the original handler with last method;
const wrappedHandler = last(handler);

const btnEl = document.querySelector("#btn");
// add the wrapped event handler
btnEl.addEventListener("click", (e) => {
  wrappedHandler(e)
    .then((res) => {
      result = res;
      console.log("result", result); // when click, result is task-${click times}, when quickly click btnEl 8 times, result is "task-7", because the previous 7 click are all aborted.
    })
    .catch((e) => {
      console.log("click event: ", e);
    });
});

API

limit([concurrency]) ⇒ undefined

Returns: undefined - (callback: () => Promise) => undefined

Param Type Default Description
[concurrency] number 6 default concurrency

description

English

like Promise.all, but limited the number of the concurrent promises.

When one promise resolved, then take the next pendingPromise unless reach the limited number again.

When all the pending promises resolved, the return promise is resolved with result corresponding to the pending promises like Promise.all.

the result contains the rejected value(mostly Error) when the corresponding pending promise was rejected.

Chinese

类似于 Promise.all 方法,但是会限制并发的 promise 数量。

每当其中一个 promise 被 resolve 后,接着取下一个 pending promise,直到再次达到限制数。

所有的 pending promises 都 resolve 后(或者其中有 reject),返回带着 result 的 promise,result 的元素顺序与 pending promise 是一一对应的,其中可能包含 Error(当对应的 promise 被 reject)。

last(fn) ⇒ function

Returns: function - () => Promise: the function to execute the async task function

Param Type Description
fn function async task function

description

English

resolve the last promise among a sequence of pending promises generated over time, usually used in handling the frequently triggered async task, like the below scenarios:

  1. In the input field, quickly type to display a dropdown list showing the response results for the current input text.
  2. quickly click, and show result of last click;

sometime, debounce or throttle can also resolve the same problem;

Chinese

随时间产生的 promise 序列里,将最后一个 promise 的结果 resolve 出去。 通常用于频繁触发的异步任务场景:

  1. 在输入框中快速输入,下拉列表展示当前输入文本的响应结果;
  2. 快速点击,展示最近点击的结果;

防抖或者节流可以解决类似的问题

About

provide promise extra functions

Resources

License

Stars

Watchers

Forks

Packages

No packages published