Created
June 23, 2020 11:28
-
-
Save gildniy/d72866321f377d461c3d4d2d805ab4b4 to your computer and use it in GitHub Desktop.
Why setTimeOut is not always a good option?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://jj09.net/settimeout-considered-harmful/ | |
// NO TIMEOUT | |
let someVar1 = 0; | |
const changeVar1 = () => { | |
someVar1 = 10; | |
return someVar1; | |
}; | |
describe("\"changeVar1\" (no timeout)", () => { | |
it("should return 10", () => { | |
expect(changeVar1()).toBe(10); | |
}); | |
}); | |
//============================================================================== | |
// USING SETTIMEOUT | |
let someVar2 = 0; | |
const changeVar2 = () => { | |
setTimeout(() => { | |
someVar2 = 10; | |
}, 10); | |
return someVar2; | |
}; | |
describe("\"changeVar2\"", () => { | |
it("should not equal to 10 but undefined -" + | |
" asynchronous function but not asynchronous in test", () => { | |
expect(changeVar2()).not.toBe(10); | |
expect(changeVar2()).toBe(0); | |
}); | |
it("should not equal to 10 -" + | |
" asynchronous function and in test with the same timeout", () => { | |
setTimeout(() => { | |
expect(changeVar2()).not.toBe(10); | |
expect(changeVar2()).toBe(0); | |
}, 10); | |
}); | |
it("should equal to 10 -" + | |
" asynchronous function and in test with a greater time in test", () => { | |
setTimeout(() => { | |
expect(changeVar2()).toBe(10); | |
}, 20); | |
}); | |
}); | |
//============================================================================== | |
let someVar3 = 0; | |
const changeVar3 = () => { | |
setTimeout(() => { | |
if (someVar3 !== 0) someVar3 = 10; | |
}, 10); | |
return someVar3; | |
}; | |
describe("\"changeVar3\"", () => { | |
it("should equal to 10 - someVar3 != 0", () => { | |
setTimeout(() => { | |
expect(changeVar3()).toBe(0); | |
}, 20); | |
}); | |
}); | |
//============================================================================== | |
let someVar4 = 0; | |
const changeVar4 = () => { | |
setTimeout(() => { | |
if (someVar4 !== 0) someVar4 = 10; | |
}, 50); | |
return someVar4; | |
}; | |
describe("\"changeVar4\"", () => { | |
it("should equal to 10 - someVar4 != 0", () => { | |
setTimeout(() => { | |
expect(changeVar4()).toBe(0); | |
}, 20); | |
}); | |
}); | |
//============================================================================== | |
// HERE IS THE UNEXPECTED SITUATION | |
let someVar5 = 0; | |
const changeVar5 = () => { | |
setTimeout(() => { | |
if (someVar5 === 0) someVar5 = 10; | |
}, 50); | |
return someVar5; | |
}; | |
describe("\"changeVar5\"", () => { | |
it("should equal to 10 - someVar5 === 0 - 0", () => { | |
setTimeout(() => { | |
expect(changeVar5()).toBe(0); | |
}, 20); | |
}); | |
it("should equal to 10 - someVar5 === 0 - 10", () => { | |
setTimeout(() => { | |
expect(changeVar5()).toBe(0); | |
}, 60); | |
}); | |
}); | |
// COMPLEX CASES | |
// ============= | |
let someVar6 = 0; | |
const changeVar6A = () => { | |
setTimeout(() => { | |
someVar6++; | |
}, 10); | |
}; | |
const changeVar6B = () => { | |
setTimeout(() => { | |
changeVar6A(); | |
someVar6 = 10; | |
}, 10); | |
return someVar6; | |
}; | |
describe("\"changeVar6\"", () => { | |
it("should equal to 10 - A", () => { | |
setTimeout(() => { | |
expect(changeVar6B()).toBe(10); | |
}, 20); | |
}); | |
it("should equal to 11 - B", () => { | |
setTimeout(() => { | |
expect(changeVar6B()).toBe(11); | |
}, 21); | |
}); | |
}); | |
// SOLUTION | |
// Use Polling methods: https://davidwalsh.name/javascript-polling | |
const poll = (fn, callBack, errorBack, timeout, interval) => { | |
const endTime = Number(new Date()) + (timeout || 2000); | |
interval = interval || 100; | |
(function p () { | |
// If the condition is met, we're done! | |
if (fn()) { | |
callBack(); | |
} // If the condition isn't met but the timeout hasn't elapsed, go again | |
else if (Number(new Date()) < endTime) { | |
setTimeout(p, interval); | |
} // Didn't match and too much time, reject! | |
else { | |
errorBack(new Error("timed out for " + fn + ": " + arguments)); | |
} | |
})(); | |
}; | |
describe("\"changeVar6\"", () => { | |
it("should equal to 11 - Using Polling", () => { | |
let testResp; | |
poll( | |
() => testResp = changeVar6B(), | |
() => expect(testResp).toEqual(11), | |
() => expect(testResp).not.toEqual(11) | |
); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment