So I am trying to write a logging HOC that will take a function and log the result of that function. I would like this hoc to be able to log the result of any function whether that function returns a promise or a value. This is what I have so far:
const logFn = (x) => {
return (...args) => {
const result = x(...args);
console.log(`result: ${result}`);
return result;
}
};
I would like to have this function handle the case when x returns a promise. I know a hacky way to do it (typeof result === object && typeof result.then === function)
but this seems brittle. I am nearly sure there is a more elegant way to do this but I am struggling to find it.
I have included a failing jest test below:
import logFn from './logFn';
describe('logFn', () => {
let outputData;
beforeEach(() => {
const storeLog = inputs => (outputData += inputs);
console["log"] = jest.fn(storeLog);
require('./logFn');
outputData = ""
});
it('handles async functions', () => {
const add2P = (x, y) => Promise.resolve(x + y);
const logAdd2 = logFn(add2P);
const expected = add2P(1,2).then((data) => data);
const actual = logAdd2(1,2);
expect(outputData).toBe('result: 3');
expect(actual).toEqual(expected);
})
});
bonus points if you can help me clean up the beforeEach.
This has the unfortunate side effect of not logging synchronously, but you could try this.
const logFn = (x) => {
return (...args) => {
const result = x(...args);
Promise.resolve(result).then(function(value) {
console.log(`result: ${value}`);
})
return result;
}
};
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve
While this answer isn't much different from @lemieuxster's answer , there is one major difference.
const logFn = fn => function () {
const result = fn.apply(this, arguments);
Promise.resolve(result).then(value => { console.log(`result: ${value}`); });
return result;
};
This preserves the calling context if, for example, you want to logify member methods:
const logFn = fn => function () { const result = fn.apply(this, arguments); Promise.resolve(result).then(value => { console.log(`result: ${value}`); }); return result; }; const foo = { bar: 'Hello, world!', doSomething: logFn(function () { return this.bar; }) }; foo.doSomething();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.