Skip to content

创建一个单例模式promise调用函数,多个地方调用同一个promise共享同一个实例

License

Notifications You must be signed in to change notification settings

qiuwenxing/only-promise

Repository files navigation

only-promise

创建一个单例模式Promise调用函数,多处地方在同一时间调用同一个Promise函数时共享同一个Promise实例,支持Typescript

使用

npm 安装

npm install only-promise -S

使用方法

import { onlyPromise } from "only-promise";

const getTime = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(Date.now());
    }, 1000);
  });
};

const onlyGetTime = onlyPromise(getTime);

onlyGetTime().then((res) => {
  console.log("res", res);
});

Example

test1

import { onlyPromise } from "only-promise";

const getTime = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(Date.now());
    }, 1000);
  });
};
// 不设置缓存时间
const onlyGetTime = onlyPromise(getTime);

for (let i = 0; i < 3; i++) {
  onlyGetTime()
    .then((res) => {
      console.log("res", res);
    })
    .catch((err) => {
      console.log("err", err);
    });
}

setTimeout(() => {
  onlyGetTime().then((res) => {
    console.log("result", res);
  });
}, 3000);

// res 1708251128183
// res 1708251128183
// res 1708251128183
// result 1708251131201

test2

import { onlyPromise } from "only-promise";

const getTime = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(Date.now());
    }, 1000);
  });
};
// 设置缓存时间5秒,单位毫秒
const onlyGetTime = onlyPromise(getTime, 5000);

for (let i = 0; i < 3; i++) {
  onlyGetTime()
    .then((res) => {
      console.log("res", res);
    })
    .catch((err) => {
      console.log("err", err);
    });
}

setTimeout(() => {
  onlyGetTime().then((res) => {
    console.log("result1", res);
  });
}, 3000);

setTimeout(() => {
  onlyGetTime().then((res) => {
    console.log("result2", res);
  });
}, 10000);

// res 1708251344268
// res 1708251344268
// res 1708251344268
// result1 1708251344268  在缓存时间内的结果保持不变
// result2 1708251350275  超过缓存时间的结果会才会变化

token 无感刷新,这里只做简单处理,实际场景会更复杂一些

import axios from "axios";
import { onlyPromise } from "only-promise";
import Cookies from "js-cookie";
import * as jwt from "jsonwebtoken";

const http = axios.create({});

const getAccessToken = (refreshToken) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("新的access token:" + Date.now());
    }, 1500);
  });
};
// 由于可能会同时发起多个请求,如果不使用该方式会导致多次刷新token
const singleGetAccessToken = onlyPromise(getAccessToken);

http.interceptors.request.use(async (config) => {
  const token = Cookies.get("accessToken");
  if (!token) return config;
  // 解析token内容
  const jwtData = jwt.decode(token, { complete: true });
  if (jwtData && jwtData.payload) {
    const tokenData = jwtData.payload;
    const curNowTime = Date.now() / 1000;
    // 判断token是否已过期,如果已过期就重新获取新token
    if (tokenData.exp < curNowTime) {
      const refreshToken = Cookies.get("refreshToken");
      const newToken = await singleGetAccessToken(refreshToken);
      Cookies.set("accessToken", newToken);
      config.headers["Authorization"] = newToken;
    }
  }
  return config;
});

About

创建一个单例模式promise调用函数,多个地方调用同一个promise共享同一个实例

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published