简体   繁体   English

等待带有setTimeout的函数完成而不会篡改该函数

[英]Waiting for function with a setTimeout to complete without tampering with that function

So basically I have a function that has a setTimeout within it like so: 所以基本上我有一个函数,其中包含setTimeout ,如下所示:

function foo(){
    console.log('starting');
    setTimeout(function(){
        console.log('done');
    }, 2000); // some arbitrary delay
}

and I want to call this function, have it truly complete, and then call a second function when it has ended: 我想调用此函数,使其真正完成,然后在结束时调用第二个函数:

foo();
secondFunction();

Is there a way that I can wait for foo() to finish running, including its setTimeout call, before secondFunction() fires? 有没有一种方法可以在secondFunction()触发之前等待foo()完成运行,包括其setTimeout调用? I suspect there is a way to do this with Promises because I've seen this problem solved with Promises before, however all the solutions I've seen includes tampering with the initial function that has the setTimeout ; 我怀疑使用Promises可以实现此目的,因为我之前已经看过使用Promises解决了此问题,但是我看到的所有解决方案都包括篡改具有setTimeout的初始函数; in my situation I cannot alter foo() at all. 在我的情况下,我根本无法更改foo()

Is there a way to solve this problem without altering foo() at all? 有没有办法解决这个问题而根本不更改foo() This means I can't create Promises inside foo() nor can I add a callback function to foo() explicitly. 这意味着我不能在foo()创建Promises,也不能显式地向foo()添加回调函数。

You can monkey-patch setTimeout because it's a property of the global object: 您可以设置setTimeout猴子补丁,因为它是全局对象的属性:

function trapTimeout() {
    return new Promise(function(resolve, reject) {
        var setTimeout = window.setTimeout;
        window.setTimeout = function(cb, delay) {
            var args = [].slice.call(arguments, 2);
            setTimeout.call(window, function() {
                window.setTimeout = setTimeout;
                cb.apply(null, args);
                resolve();
            }, delay, ctx);
        }
    });
}

var trap = trapTimeout();
foo();
trap.then(function() { console.log('really done') });

This is a moderately nasty hack. 这是一个中等讨厌的黑客。 It could well barf if something else creates a timer after this code (since the .then call doesn't stop any following code or the event loop from running, and the monkey patching remains in place until after the timeout is triggered). 如果其他人在此代码之后创建了一个计时器,则可能会受到挫败(因为.then调用不会停止任何后续代码或事件循环运行,并且猴子跳动一直保持到触发超时之前)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM