你认为这样的对象函数怎么样?
const stc = {
delayTimer: {},
sleep: (m, name) => new Promise(r => stc.delayTimer[name] = setTimeout(r, m)),
sleepProlong: async (ms, name)=> {
if (stc.delayTimer[name])
clearTimeout(stc.delayTimer[name]);
delete stc.delayTimer[name];
return await stc.sleep(ms, name);
}
}它用于延迟,但是当您在设定的时间到期之前再次调用它时,它从一开始就清除计数器并计数,不再释放函数。
async function s (){
console.log("wy");
await stc.sleepProlong(5000, "mek");
console.log("my");
}例如,在控制台中,您将在上次触发5秒之前启动s(),"we“将不会出现。当您停止时,它将完成最后的计数和“我们”将显示。
你认为如何?你能做得更好吗?
发布于 2018-12-09 15:56:38
不知道你会用这个做什么,我只能回答你的问题。
stc的行为不是这个问题的标题所暗示的,因为它很容易使它失败或以一种非直观的方式行为。
请考虑以下使用示例
stc.sleep(1000, "test").then(()=>log("Test timeout"); // this promise is never resolved
setTimeout(()=>{
stc.sleepProlong(2000, "test").this(()=>log("Test prolonged timeout")
},200);第一个承诺尚未兑现,永远不会得到解决。
sleepProlong时,都会留下另一个未解决的承诺。sleepProlong被称为“延长睡眠”的名字时,它意味着“延长睡眠”,但是如果睡眠已经超时,它就会创建一个新的睡眠?stc接口公开了delayTimer,使得stc的状态不可信。从问题的标题中我可以预料到
sleep调用name没有任何作用。m,另一个函数调用ms。delete stc.delayTimer[name];,因为您通过在下一行调用sleep来覆盖该值。{}来分隔语句块是一种坏习惯,总是用{...}.You had if (stc.delayTimer[name]) clearTimeout(stc.delayTimer[name]);分隔语句块是最好的方法。clearTimeout将忽略undefined并已经超时句柄。因此,if (stc.delayTimer[name]) { clearTimeout(stc.delayTimer[name]); }可以是clearTimeout(stc.delayTimer[name]);,而不是改变行为。m或ms作为第一个论点是错误的。将name放在第一位,然后延迟似乎更自然(因此更容易记住)await在async function中返回的承诺,异步函数会自动完成这一任务。delayTimer中的条目发生了变异,那么您就失去了保持stc's正确行为的能力。您可以通过闭包来保护它。在不改变您代码的行为的情况下,我进行了上述要点中概述的更改,并修改了一些名称。
const stc = (() => {
const handles = {};
return {
sleep(name, time) { return new Promise(r => handles[name] = setTimeout(r, time)) },
async prolong(name, time) {
clearTimeout(handles[name]);
return stc.sleep(name, time);
}
};
})();https://codereview.stackexchange.com/questions/209295
复制相似问题