Лучший способ написать функцию, которая либо возвращает значение, либо разрешенное обещание - PullRequest
0 голосов
/ 21 сентября 2018

Итак, я пытаюсь написать 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), но это кажется хрупким.Я почти уверен, что есть более элегантный способ сделать это, но я изо всех сил пытаюсь его найти.

Я включил нижеприведенный тест шутки ниже:

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

бонусных баллов, если вы можетепомогите мне очистить до каждого.

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Хотя этот ответ не сильно отличается от ответа @ lemieuxster , есть одно существенное отличие.

const logFn = fn => function () {
  const result = fn.apply(this, arguments);
  Promise.resolve(result).then(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;
};

const foo = {
  bar: 'Hello, world!',
  doSomething: logFn(function () {
    return this.bar;
  })
};

foo.doSomething();
0 голосов
/ 21 сентября 2018

К сожалению, побочный эффект заключается не в синхронной регистрации, но вы можете попробовать это.

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

...