Reputation: 5637
So basically I have a function that has a setTimeout
within it like so:
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? 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
; in my situation I cannot alter foo()
at all.
Is there a way to solve this problem without altering foo()
at all? This means I can't create Promises inside foo()
nor can I add a callback function to foo()
explicitly.
Upvotes: 3
Views: 149
Reputation: 340045
You can monkey-patch setTimeout
because it's a property of the global object:
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).
Upvotes: 3