Skip to content

Instantly share code, notes, and snippets.

@gildniy
Created June 23, 2020 11:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gildniy/d72866321f377d461c3d4d2d805ab4b4 to your computer and use it in GitHub Desktop.
Save gildniy/d72866321f377d461c3d4d2d805ab4b4 to your computer and use it in GitHub Desktop.
Why setTimeOut is not always a good option?
// 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