Javascript 等待最长N秒,等待事件发生

Javascript 等待最长N秒,等待事件发生,javascript,es6-promise,Javascript,Es6 Promise,在我的JS代码中,我需要等待3秒钟,标志才会为真。我做了以下工作: const waitForSomethingToBeTrue = (something) => { const maxWaitingTime = 3 * 1000; let promises = []; for (let i = 100; i < maxWaitingTime; i += 100) { promises.push(new Promise((resolve, r

在我的JS代码中,我需要等待3秒钟,标志才会为真。我做了以下工作:

const waitForSomethingToBeTrue = (something) => {
    const maxWaitingTime = 3 * 1000;

    let promises = [];
    for (let i = 100; i < maxWaitingTime; i += 100) {
        promises.push(new Promise((resolve, reject) => {
            setTimeout(() => {
                if (something()) {
                    resolve();
                } else {
                    reject(something.name + " didn't happen in " + i + "miliseconds.");
                }
            }, i);
        }));
    }

    return Promise.any(promises).catch(() => {
        return Promise.reject(`${something.name} didn't happen in maximum allowed
            time (${maxWaitingTime} msecs).`);
    });
};
正如您所注意到的,我的方法有几个问题:

我创建了许多不必要的超时,例如,如果200毫秒的承诺得到了解决,其余的都是不必要的,并且已经解决了 我使用的是Promise.any,它还没有得到官方的支持。我通过使用Promise.all编写一个垫片来解决这个问题,所有这些都是相反的,但官方支持的方法会更好。
在没有上述问题的情况下,我如何解决这个问题?

做出一个承诺,在内部进行检查,不断检查状态

函数myFunction{ var x=Math.floorMath.random*30; 返回x==10; } 函数waitFormethod,max{ var start=Date.now; 返回新的PromiseSolve,拒绝=>{ 功能检查{ var结果=方法; 如果结果{ 决定 }否则,如果Date.now-开始>最大值{ 拒绝 }否则{ window.setTimeoutcheck,100; } } 检查 }; } waitFormyFunction,3000 .then=>console.log'good'
.catch=>console.log'bad' 做出一个承诺,检查内部,不断检查状态

函数myFunction{ var x=Math.floorMath.random*30; 返回x==10; } 函数waitFormethod,max{ var start=Date.now; 返回新的PromiseSolve,拒绝=>{ 功能检查{ var结果=方法; 如果结果{ 决定 }否则,如果Date.now-开始>最大值{ 拒绝 }否则{ window.setTimeoutcheck,100; } } 检查 }; } waitFormyFunction,3000 .then=>console.log'good'
.catch=>console.log'bad' 您可以只使用一个setInterval,然后清除它并解析/拒绝一个承诺:

const gen=function t{ 设值=假; setTimeout=>value=true,t; 返回=>值; }; const success=gen2500; 常数误差=gen3500; const watch=value=>{ 返回新的PromiseSolve,拒绝=>{ const interval=setInterval=>{ 如果值{ 正确的; 清晰间隔; } }, 100; 设置超时=>{ 清晰间隔; 拒绝“未及时完成”; }, 3000 }; } watchsuccess.thenconsole.log.catchconsole.error;
watcherr.thenconsole.log.catchconsole.error 您可以只使用一个setInterval,然后清除它并解析/拒绝一个承诺:

const gen=function t{ 设值=假; setTimeout=>value=true,t; 返回=>值; }; const success=gen2500; 常数误差=gen3500; const watch=value=>{ 返回新的PromiseSolve,拒绝=>{ const interval=setInterval=>{ 如果值{ 正确的; 清晰间隔; } }, 100; 设置超时=>{ 清晰间隔; 拒绝“未及时完成”; }, 3000 }; } watchsuccess.thenconsole.log.catchconsole.error;
watcherr.thenconsole.log.catchconsole.error 我只需要一个承诺就可以做到这一点,要么决定某件事是否属实,要么拒绝它

const waitforsomethingtobetreal=something=>{ 返回新承诺解析,拒绝=>{ let start=new Date.getTime; const intervalId=setInterval=>{ 如果有什么{ 清晰有效; 决定 } 否则{ 计时器=new Date.getTime-开始; 如果计时器>3000{ 清晰有效; 时间太长了; } } },100; }; } //下面的测试代码只是通过单击按钮将全局bool设置为true var globalBool=false; 异步函数测试{ document.querySelectorclickme.addEventListenerclick,=>globalBool=true; 试一试{ 等待等待某件事OBETURE=>globalBool; console.logIt是真的; } 捕捉错误{ console.logerror; } } 睾丸;
单击“我来实现某事”我只需要一个承诺就可以做到这一点,如果某事是真的,就解决它,如果它到了时间,就拒绝它

const waitforsomethingtobetreal=something=>{ 返回新承诺解析,拒绝=>{ let start=new Date.getTime; const intervalId=setInterval=>{ 如果有什么{ 清晰有效; 决定 } 否则{ 计时器=new Date.getTime-开始; 如果计时器>3000{ 清晰有效; 时间太长了; } } },100; }; } //下面的测试代码只是通过单击按钮将全局bool设置为true var globalBool=false; 异步函数测试{ document.querySelectorclickme.addEventListenerclick,=>globalBool=true; 试一试{ 等待等待某件事OBETURE=>globalBool; console.logIt是真的; } 捕捉错误{ console.logerror; } } 睾丸; 点击
下面是一个将async await与名为delay的promisified setTimeout结合使用的实现:

const delay=ms=>new Promiseresolve=>setTimeoutresolve,ms; const waitforsomethingtobetreal=异步某物,放弃=>{ 让expired==>true; delaygiveUp.then=>something=过期; 有东西在等着你; 如果某物===过期,则抛出过期; 回归成功; }; //测试按钮是否及时按下 buttonClicked=false; document.querySelectorbutton.addEventListenerclick,=>buttonClicked=true; waitForSomethingToBeTrue=>按钮点击,5000 .thenconsole.log .catchconsole.log; 成真
按下按钮5秒钟即可获得成功。如果延迟过期,则会报告此情况。以下是一个使用async await和promisified setTimeout(称为延迟)组合的实现:

const delay=ms=>new Promiseresolve=>setTimeoutresolve,ms; const waitforsomethingtobetreal=异步某物,放弃=>{ 让expired==>true; delaygiveUp.then=>something=过期; 有东西在等着你; 如果某物===过期,则抛出过期; 回归成功; }; //测试按钮是否及时按下 buttonClicked=false; document.querySelectorbutton.addEventListenerclick,=>buttonClicked=true; waitForSomethingToBeTrue=>按钮点击,5000 .thenconsole.log .catchconsole.log; 成真
按下按钮5秒钟即可获得成功。如果该延迟过期,则会报告该延迟。可能是一个单一的设置间隔,跟踪它已经持续了多长时间,如果太长,则清除该间隔并拒绝承诺。只是别忘了在成功时清除间隔以停止轮询。可能是一个setInterval,记录它已经过了多长时间,如果太长,则清除间隔并拒绝承诺。只是别忘了清除成功的间隔来停止投票。所有答案都很好,谢谢大家。我要标记这个,因为它在编写测试时遇到了麻烦。因为setTimeout/Interval会超时,所以它的计时器不准确。“小时间,没什么大不了的,更大的时间框架,更大的事情。”埃帕斯卡雷罗说。这是一条巨大的捷径,我应该做得更好。现在更新。所有答案都很好,谢谢大家。我要标记这个,因为它在编写测试时遇到了麻烦。因为setTimeout/Interval会超时,所以它的计时器不准确。“小时间,没什么大不了的,更大的时间框架,更大的事情。”埃帕斯卡雷罗说。这是一条巨大的捷径,我应该做得更好。现在更新。