{"id":28337682,"url":"https://github.com/lei-mu/single-promises","last_synced_at":"2025-08-22T17:12:34.244Z","repository":{"id":193215770,"uuid":"688340535","full_name":"lei-mu/single-promises","owner":"lei-mu","description":"Create a singleton pattern Promise-invoking function","archived":false,"fork":false,"pushed_at":"2024-12-05T07:36:48.000Z","size":19,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-26T23:47:07.357Z","etag":null,"topics":["promise","single","single-promise"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lei-mu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-09-07T06:39:30.000Z","updated_at":"2024-12-05T07:49:37.000Z","dependencies_parsed_at":"2023-09-07T08:25:50.369Z","dependency_job_id":"52e3e3ed-4cf4-4044-905c-10f621f1c83d","html_url":"https://github.com/lei-mu/single-promises","commit_stats":null,"previous_names":["lei-mu/single-promises"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/lei-mu/single-promises","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lei-mu%2Fsingle-promises","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lei-mu%2Fsingle-promises/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lei-mu%2Fsingle-promises/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lei-mu%2Fsingle-promises/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lei-mu","download_url":"https://codeload.github.com/lei-mu/single-promises/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lei-mu%2Fsingle-promises/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260850485,"owners_count":23072540,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["promise","single","single-promise"],"created_at":"2025-05-26T23:45:37.052Z","updated_at":"2025-08-22T17:12:34.225Z","avatar_url":"https://github.com/lei-mu.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# single-promises\n\n[![npm](https://img.shields.io/npm/l/single-promises \"npm\")](https://www.npmjs.com/package/single-promises \"npm\")\n[![npm](https://img.shields.io/npm/v/single-promises \"npm\")](https://www.npmjs.com/package/single-promises \"npm\")\n[![github](https://img.shields.io/github/package-json/v/lei-mu/single-promises \"github\")](https://github.com/lei-mu/single-promises \"github\")\n[![github stars](https://img.shields.io/github/stars/lei-mu/single-promises.svg \"github stars\")](https://github.com/lei-mu/single-promises \"github stars\")\n\n生成一个单例模式的promise 调用函数。\n\n简体中文 | [English ](./README_EN.md)\n\n## 使用\n\n### npm\n\n````cmd\nnpm install single-promises -S\n````\n\nimport\n\n```` js\nimport {singlePromise, version} from 'single-promises'\n````\n\nrequire\n\n```` js\nconst {singlePromise, version} = require('single-promises')\n````\n\n\n\n### CDN\n\njsDelivr CDN\n\n```` js\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/single-promises@1.0.0/dist/single-promises.iife.js\"\u003e\u003c/script\u003e\n````\n\nunpkg CDN\n\n```` js\n\u003cscript src=\"https://unpkg.com/single-promises@1.0.0/dist/single-promises.iife.js\"\u003e\u003c/script\u003e\n````\n\n```` js\n\u003cscript\u003e\n    const { singlePromise, version } = singlePromises\n\u003c/script\u003e\n````\n\n\n\n## Example\n\n### test\n\n```` js\nimport { singlePromise } from 'single-promises'\nconst getTime = () =\u003e {\n  return new Promise((resolve, reject) =\u003e {\n    setTimeout(() =\u003e {\n      resolve(Date.now())\n    }, 1000)\n  })\n}\n\nconst singleGetTime = singlePromise(getTime)\n\nfor (let i = 0; i \u003c 5; i++) {\n  singleGetTime().then(res =\u003e {\n    console.log('res', res)\n  })\n}\n// res 1694058404950\n// res 1694058404950\n// res 1694058404950\n// res 1694058404950\n// res 1694058404950\n// 输出5遍结果,但只获取了一次当前时间\n````\n\n\n\n\n\n### access_token 无痛刷新\n\n实际的实现比这个更加复杂，这里只做关键代码的示例。\n\n```` js\nimport axios from 'axios'\nimport { singlePromise } from 'single-promises'\nimport Cookies from 'js-cookie'\n\nconst http = axios.create({})\n\nconst getAccessToken = (refreshToken) =\u003e {\n  return new Promise((resolve, reject) =\u003e {\n    setTimeout(() =\u003e {\n      resolve('新的access token：' + Date.now())\n    }, 1500)\n  })\n}\n\nconst singleGetAccessToken = singlePromise(getAccessToken)\n\nhttp.interceptors.request.use(async config =\u003e {\n  const token = Cookies.get('access_token')\n  if (!token) {\n    const refreshToken = Cookies.get('refresh_token')\n    const res = await singleGetAccessToken(refreshToken)\n    Cookies.set('access_token', res)\n  }\n  return config\n})\n````\n\n### 多组件api\n\n多个组件同时获取用户信息，使用singlePromise 包装，只需要调用一次。\n\n```` js\n// api.js\n// 多次调用，在api 请求未响应前，只会调用一次api请求，请求响应后会把api 响应结果响应给对应的调用。调用结束后 1000 ms 内，再次调用会直接返回上次调用的结果，不会再次调用api 请求。调用结束后 1000 ms 后，再次调用会直接调用api请求\nconst getUserInfo = singlePromise((params) =\u003e axios.get('api/userInfo', {params}), {cache: 1000})\n````\n\n````vue\n\u003cscript\u003e\n/** Header.vue **/\n{\n    created () {\n    \tgetUserInfo()\n    }\n}\n\u003c/script\u003e\n````\n````vue\n\u003cscript\u003e\n/** Footer.vue **/\n{\n    created () {\n    \tgetUserInfo()\n    }\n}\n\u003c/script\u003e\n````\n````vue\n\u003cscript\u003e\n/** Article.vue **/\n{\n    created () {\n    \tgetUserInfo()\n    }\n}\n\u003c/script\u003e\n````\n````vue\n\u003ctemplate\u003e\n\u003cdiv\u003e\n    \u003cHeader/\u003e\n\t\u003cArticle/\u003e\n\t\u003cFooter/\u003e\n\u003c/div\u003e\n\n\u003c/template\u003e\n\u003cscript\u003e\n/** Layout.vue **/\n{\n    created () {\n    \tgetUserInfo()\n    }\n}\n\u003c/script\u003e\n````\n\n多个组件同时调用，只会调用一次api 请求\n\n\n\n## API\n\n### singlePromise\n\n第一个参数接收一个函数，第二个参数接收一个配置项对象。返回一个函数。\n\nsinglePromise(fn[, options])\n\nReturn: `Function`\n\n#### fn\n\nType: `Function`\n\n要调用的函数。当执行返回的函数时，`this`上下文和所有参数将按原样传递给 `fn`。fn 函数可以返回promise,或其他，因为在`singlePromise `函数内部，`fn`函数将被`Promise.resolve` 函数包裹。\n\n#### options\n\nType: `Object`\n\nDefault: `{cache: 0}`\n\n可选。配置项\n\n#### options.cache\n\nType: `Number`\n\nDefault: `0`\n\n`fn`函数返回结果后的缓存时间,单位`ms`。在缓存时间内，下次调用将直接返回缓存的结果。默认0 不缓存。缓存时间从`fn` 函数返回`fulfilled`状态开始算起，如果`fn`函数返回`rejected`状态则不缓存。\n\n#### 返回函数\n\n```` js\nconst handle = singlePromise(() =\u003e Promise.resolve('response'), {cache: 1500})\n````\n\nReturn: `Promise`\n\nhandle 函数调用返回一个promise, 这个promise的 `fulfilled`/ `rejected` 状态取决于 `fn`函数返回的`promise` 的状态。当执行`handle` 函数时，`this`上下文和所有参数将按原样传递给 `fn`\n\n#### handle.clear\n\nType: `Function`\n\n清除缓存结果函数。调用将清除上次的缓存结果。\n\n#### handle.update\n\nType: `Function`\n\nhandle.update(options)\n\n更新`options`函数。`handle.update({cache: 1000})`,调用后将更新handle 的配置。\n\n\n\n### version\n\n当前包的版本号\n\n\n\n## 常见问题\n\n\n### 如果在vue 使用\n\n注意：需要在 `data` 配置项 调用创建，不然会丢失 `handle.clear`、`handle.update` 方法\n\n```` vue\n\u003cscript\u003e\n// vue2\nimport { singlePromise } from 'single-promises'\n{\n\tdata () {\n\t\treturn {\n            \tsingleGetUserInfo: singlePromise((params) =\u003e axios.get('api/userInfo', {params}), {cache: 1000})\n\t\t\t}\n\t}\n}\n\u003c/script\u003e\n````\n\n\n\n### 与`throttle`  、`debounce` 的区别\n\nthrottle/debounce 都取决于指定时间内做什么事，而singlePromise 取决于 `fn`函数返回的promise `pending` 状态时做什么事\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flei-mu%2Fsingle-promises","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flei-mu%2Fsingle-promises","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flei-mu%2Fsingle-promises/lists"}