Javascript 编写返回值或解析承诺的函数的最佳方法

Javascript 编写返回值或解析承诺的函数的最佳方法,javascript,asynchronous,promise,higher-order-functions,Javascript,Asynchronous,Promise,Higher Order Functions,因此,我试图编写一个日志记录HOC,它将接受一个函数并记录该函数的结果。我希望这个hoc能够记录任何函数的结果,无论该函数返回承诺还是值。这就是我到目前为止所做的: const logFn = (x) => { return (...args) => { const result = x(...args); console.log(`result: ${result}`); return result; } }; 我想让这个函数处理x返回承诺的

因此,我试图编写一个日志记录HOC,它将接受一个函数并记录该函数的结果。我希望这个hoc能够记录任何函数的结果,无论该函数返回承诺还是值。这就是我到目前为止所做的:

const logFn = (x) => {
  return   (...args) => {
    const result =  x(...args);
    console.log(`result: ${result}`);
    return result;
  }
};
我想让这个函数处理x返回承诺的情况。我知道一种很有技巧的方法
(typeof result==object&&typeof result.then==function)
,但这似乎很脆弱。我几乎可以肯定有一种更优雅的方式可以做到这一点,但我正在努力寻找它

我在下面列出了一个失败的jest测试:

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);
  })
});

如果你能在每次之前帮我清理房间,就可以获得额外的积分

这有一个不幸的副作用,就是不能同步登录,但是您可以试试这个

const logFn = (x) => {
  return   (...args) => {
    const result =  x(...args);
    Promise.resolve(result).then(function(value) {
     console.log(`result: ${value}`);
    })
    return result;
  }
};

虽然这个答案与其他答案没有太大区别,但有一个主要区别

const logFn = fn => function () {
  const result = fn.apply(this, arguments);
  Promise.resolve(result).then(value => { console.log(`result: ${value}`); });
  return result;
};
例如,如果要对成员方法进行登录,则会保留调用上下文:

constlogfn=fn=>function(){
const result=fn.apply(这是参数);
resolve(result).then(value=>{console.log(`result:${value}`);});
返回结果;
};
常数foo={
酒吧:“你好,世界!”,
doSomething:logFn(函数(){
返回此.bar;
})
};

foo.doSomething()如果函数返回承诺数组或具有承诺属性的对象,该怎么办?同样,在您的示例中,您失去了将调用上下文传递给所提供函数的能力。如果你想这样做,你需要使用一个普通函数而不是箭头函数。这些都是很好的要点。此处不支持返回承诺数组或具有承诺属性的对象的函数。我也不喜欢箭头函数,但我认为我不需要调用上下文。你提到的“不幸的副作用”是不可避免的。你不能阻止等待承诺解决的线程,因为这根本不是承诺的工作方式。而且,这永远不会同步记录。这没什么错,但你应该纠正你回答中的误导性陈述。无论
result
是否是承诺,console.log()
都将是异步的。