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

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.

主站蜘蛛池模板: 桃江县| 简阳市| 台南县| 桂阳县| 中江县| 广灵县| 会昌县| 五家渠市| 兰溪市| 资兴市| 贵定县| 来宾市| 江孜县| 凤冈县| 班戈县| 陕西省| 夏河县| 陕西省| 宜都市| 甘谷县| 连平县| 大渡口区| 兰考县| 鞍山市| 礼泉县| 鄱阳县| 乐东| 开江县| 敦化市| 精河县| 宁都县| 孟连| 景德镇市| 日喀则市| 德格县| 花莲县| 左云县| 郎溪县| 双柏县| SHOW| 安庆市|