官术网_书友最值得收藏!

An even better solution

In one of the previous solutions, we mentioned that it would be a good idea to do something every time after the first, and not silently ignoring the user's clicks. We'll write a new higher-order function, that takes a second parameter; a function to be called every time from the second call onward:

const onceAndAfter = (f, g) => {
let done = false;
return (...args) => {
if (!done) {
done = true;
f(...args);
} else {
g(...args);
}
};
};

We have ventured further in higher-order functions; onceAndAfter takes two functions as parameters and produces a third one, which includes the other two within.

You could make onceAndAfter more powerful, by giving a default value for g, along the lines of const onceAndAfter = (f, g = ()=>{}) ... so if you didn't want to specify the second function, it would still work fine, because it would call a do nothing function, instead of causing an error.

We can do a quick-and-dirty test, along with the same lines as we did earlier:

const squeak = (x) => console.log(x, "squeak!!");
const creak = (x) => console.log(x, "creak!!");
const makeSound = onceAndAfter(squeak, creak);
makeSound("door"); // "door squeak!!"
makeSound("door"); // "door creak!!"
makeSound("door"); // "door creak!!"
makeSound("door"); // "door creak!!"

Writing a test for this new function isn't hard, only a bit longer:

describe("onceAndAfter", () => {
it("should call the first function once, and the other after", () => {
func1 = () => {};
spyOn(window, "func1");
func2 = () => {};
spyOn(window, "func2");
onceFn = onceAndAfter(func1, func2);

onceFn();
expect(func1).toHaveBeenCalledTimes(1);
expect(func2).toHaveBeenCalledTimes(0);

onceFn();
expect(func1).toHaveBeenCalledTimes(1);
expect(func2).toHaveBeenCalledTimes(1);

onceFn();
expect(func1).toHaveBeenCalledTimes(1);
expect(func2).toHaveBeenCalledTimes(2);

onceFn();
expect(func1).toHaveBeenCalledTimes(1);
expect(func2).toHaveBeenCalledTimes(3);
});
});

Notice that we always check that func1 is called only once. Similarly, we check func2; the count of calls starts at zero (the time that func1 is called), and from then on, it goes up by one on each call.

主站蜘蛛池模板: 将乐县| 阿鲁科尔沁旗| 名山县| 乌拉特后旗| 丹阳市| 望都县| 天水市| 威信县| 云阳县| 孙吴县| 昌宁县| 瑞昌市| 留坝县| 瑞安市| 马尔康县| 盐城市| 信宜市| 承德县| 长沙市| 贵南县| 景德镇市| 饶阳县| 当涂县| 海丰县| 修文县| 万山特区| 乌拉特前旗| 普安县| 浮山县| 濉溪县| 延寿县| 资阳市| 牟定县| 平昌县| 通许县| 耒阳市| 泗阳县| 西贡区| 台州市| 义乌市| 克山县|