我想创建一个暴露以下接口的对象:
// Create the object that counts to three
const c = counter(3);
// c.finished is a promise that resolves when c.count() is invoked three times
c.finished.then(() => console.log('counted three times!'));
// Somewhere else, c.count() is invoked in async body
setTimeout(() => c.count(), 500);
setTimeout(() => c.count(), 1000);
setTimeout(() => c.count(), 1500);
我希望c.finished
在1.5秒后解决。
如何仅使用原生counter(countTimes)
API来编写Promise
?
公开信息:我已经a solution遇到了上述问题,想知道什么是最优雅的方法。
修改
我最初的解决方法是:
class AsyncCounter {
constructor(countTimes) {
let currentCount = 0;
this.countTimes = countTimes;
this.ready = new Promise(resolveReady => {
this.finished = new Promise(resolveFinished => {
const count = () => {
currentCount++;
if (currentCount >= this.countTimes) {
resolveFinished();
}
return currentCount;
};
this.count = () => this.ready.then(() => count());
resolveReady();
});
});
}
}
const counter = countTimes => new AsyncCounter(countTimes);
根据@Bergi的建议并根据MDN docs for executor function:
在Promise构造函数甚至返回 创建的对象
因此,上述解决方案中的ready
承诺不是必需的。
答案 0 :(得分:2)
你会写
null
或者,除了将function counter(n) {
let i=0, resolve;
return {
count() {
if (++i == n) resolve();
},
finished: new Promise(res => {
resolve = res;
})
};
}
放在外部变量之外,您也可以这样做
resolve
答案 1 :(得分:2)
这就是我可能写的方式,但是将resolveInternal
提取到外部resolve
变量中,使我觉得必须有一个更好的解决方案。不幸的是,本机Promise
API没有公开任何方法来从外部解析Promise对象。
function counter(max) {
let resolve = null;
const finished = new Promise(resolveInternal => {
resolve = resolveInternal
})
const count = () => {
if (!--max) resolve()
}
return {
count,
finished
}
}
const c = counter(3)
c.finished.then(() => console.log("counted three times!"))
setTimeout(() => c.count(), 500)
setTimeout(() => c.count(), 1000)
setTimeout(() => c.count(), 1500)