拒绝承诺并停止 socket-io 事件超时

Reject a promise and stop timeout on socket-io event

我目前正在使用以下函数在我的 Node.js 服务器脚本中模拟等待(睡眠)。

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

我正在使用它,如下所示。以这种方式使用时,将暂停执行该行下方的代码,直到经过 20 秒。

await sleep(20000)

现在我想在 socket-io 事件上打破睡眠,但我想不出正确的方法来做到这一点。

我尝试了以下代码,但它并没有打破睡眠。

// This object holds some properties
var meetings = {

}

function sleep(ms) {
  return new Promise(function(resolve,reject) => {
    var t = setTimeout(resolve, ms)
    // add the function as a "meetings" object property value
    meetings[endSleep] = function(){
      clearTimeout(t)
      reject()
    }    
  });
}

// later, using socket-io
socket.on("end_sleep",function(){
  meetings["endSleep"]()
})

如何使用此功能?非常感谢所有有用的建议。

我很想把它包装在一个 class 中,它保存返回的 Promise 的 timerId 和 reject 的状态,并在 [=15] 中使用它们=]方法。

下面演示了这一点:

class Sleeper
{
   wait(ms){
     return  new Promise( (resolve, reject) => {
        this.reject = reject;
        this.t = setTimeout(resolve,ms);
     });
   }
   
   cancel(reason){
    clearTimeout(this.t);
    this.reject(reason);
   }
}
var sleep = new Sleeper();

async function test(){
  
  try{
    await sleep.wait(5000);
    console.log("finished");
  }catch(e){
    console.log("cancelled:", e);
  }
}

document.querySelector("#cancel").addEventListener("click", () => {
   sleep.cancel("cancel button pressed");
});

test();
<button id="cancel">Cancel</button>

我添加了传递取消原因的功能,可能会有用。


在你的代码中看起来像:

var sleeper = new Sleeper();

socket.on("end_sleep",function(){
  sleeper.cancel(); // pass a reason if you wanted.
})

// your code
await sleeper.wait(20000);

我不太确定为什么会这样,但我想记下是什么让它起作用。

当我使用 resolve 而不是 reject 时,一切都解决了,如下所示。

function sleep(ms) {
  return new Promise(function(resolve,reject) => {
    var t = setTimeout(resolve, ms)
    // add the function as a "meetings" object property value
    meetings[endSleep] = function(){
      clearTimeout(t)
      resolve()
    }    
  });
}

如果有人能解释为什么会这样,请随时编辑这个答案。

在你的情况下'break'意味着'early resolving',而不是拒绝。如果您调用 reject ,则 await 语句将抛出错误并且异步函数的执行可以停止(如果未使用 try catch 块)。 代码可能看起来好一点::

const CPromise= require("c-promise2");
// cancellable sleep
function sleep(ms, signal) {
    return new CPromise((resolve, reject, {onCancel}) => {
        const timer = setTimeout(resolve, ms);
        onCancel(() => clearTimeout(timer));
    }, {signal}).catch(() => {});
}

(async()=>{
    const sleeper= sleep(30000);
    socket.on("end_sleep",function(){
        sleeper.cancel();
    });
    await sleeper;
})();

const abortController= new CPromise.AbortController();

(async()=>{
    await sleep(30000, abortController.signal);
})();

socket.on("end_sleep",function(){
    abortController.abort();
});