单例 Promise
比如有一个接口请求的 Promise:
function getUserInfo() {
return new Promise(resolve => {
API.get('getUserInfo').then(resolve);
})
}
单例 Promise 就是只会有一个 Promise,接口也就只会请求一次。以下我们来看一下怎么使用单例 Promise 的:
let promise = null; // 保存单例 Promise
$('.btn').click(() => {
if (!promise) {
promise = getUserInfo();
}
promise.then(data => {
// ...
})
})
最后的效果:连续点击按钮,但最终只会调用一次获取用户信息的接口。
为什么能这么操作,我们再来看一个简单的例子:
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const myPromise = sleep(3000); // 这里就开始执行定时器的异步操作
console.time('first await');
await myPromise;
console.timeEnd('first await');
console.time('second await');
await myPromise;
console.timeEnd('second await');
输出:
first await: 3002ms - timer ended
second await: 0ms - timer ended
该实验表明:
- 同一个 Promise 可以被多次等待,或使用 then
- 等待已经 resolve 的 Promise ,将立即解决
Promise 缓存
const userPromisesCache = new Map();
const getUserById = (userId) => {
if (!userPromisesCache.has(userId)) {
const userPromise = request.get(`https://users-service/v1/${userId}`);
userPromisesCache.set(userId, userPromise);
}
return userPromisesCache.get(userId);
};
await Promise.all([
getUserById('user1'),
getUserById('user1')
]);
这里,我们将 Promise 放入缓存中,然后将其返回给调用方。最终,获取用户信息接口只会调用一次。