Запросите базовое объяснение кода Typescript / Javascript и RxJs - PullRequest
0 голосов
/ 24 апреля 2018

Я изучаю rxjs и мне тяжело оборачиваться вокруг этих двух строк кода:

const dispatcher = fn => (...args) => appState.next(fn(...args));
const actionX = dispatcher(data =>({type: 'X', data}));

По крайней мере, часть того, почему я не понимаю, состоит в том, что он использует сокращенный синтаксис, которыйЯ еще не привыкЯ пытался расширить его, чтобы точно понять, что происходит, но не смог правильно сделать это.Например, actionX вызывает диспетчер, и функция передается как параметр, но затем фактически не запускается, пока эта же функция не будет вызвана в appState.next?Кажется, есть много функций, возвращающих функции, и это заставляет мою голову вращаться.Любое понимание будет полезно.

из этого:

import Rx from 'rxjs/Rx';

const inputEl = document.querySelector('input');
const activeEl = document.querySelector('#active');
const doneEl = document.querySelector('done');

const appState = new Rx.BehaviorSubject({todos: []});

appState.subscribe(console.log);

const dispatcher = fn => (...args) => appState.next(fn(...args));
const actionX = dispatcher(data =>({type: 'X', data}));

actionX('some data');

Этот код регистрирует это:

>{todos: Array(0)}
>{type: "X", data: "some data"}

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Более классический подход JS без функций со стрелками (=>), остальные параметры (...args) => {}) и синтаксис расширения (appState.next(fn(...args))) для:

const dispatcher = fn => (...args) => appState.next(fn(...args));

будет:

const dispatcher = function (fn) {
    return function () {
        // arguments are the parameters passed to the function
        const result = fn.apply(null, arguments);
        return appState.next(result);
    };
};

Точка этого кода, кажется, заключает в себе ваш обратный вызов (fn), переданный в dispatcher(...), так что appState обновляется с результатом обратного вызова.Это облегчает повторное использование функциональности выполнения некоторого кода и установки его в качестве следующего значения в вашем appState.Без этого вам нужно было бы не забывать каждый раз возвращать ваше значение из обратного вызова в состояние вашего приложения.

Другими словами, без использования этого шаблона ваш код выше будет:

import Rx from 'rxjs/Rx';

const inputEl = document.querySelector('input');
const activeEl = document.querySelector('#active');
const doneEl = document.querySelector('done');

const appState = new Rx.BehaviorSubject({todos: []});

appState.subscribe(console.log);

//const dispatcher = fn => (...args) => appState.next(fn(...args));
//const actionX = dispatcher(data => ({type: 'X', data}));

const actionX = function (data) {
    appState.next({type: 'X', data: data});
};

actionX('some data');

Это может быть полезно для случая, когда у вас есть одно действие, но как быть, если у вас есть несколько?Вы будете дублировать appState.next(...) для каждого из действий.Что, если отправка результата вашего обратного вызова будет более сложной?Ну, это намного больше дублирования и возможности ошибок и не синхронизированы друг с другом.Это звучит как хорошее использование функционального программирования и превращение его в функцию многократного использования:

import Rx from 'rxjs/Rx';

const inputEl = document.querySelector('input');
const activeEl = document.querySelector('#active');
const doneEl = document.querySelector('done');

const appState = new Rx.BehaviorSubject({todos: []});

appState.subscribe(console.log);

//const dispatcher = fn => (...args) => appState.next(fn(...args));
//const actionX = dispatcher(data => ({type: 'X', data}));

const dispatcher = function (state) {
    appState.next(state);
};
// or for a shorter modern version:
// const dispatcher = state => appState.next(state);

const actionX = function (data) {
    dispatcher({type: 'X', data: data});
};

actionX('some data');

В функциональном программировании существует концепция функций более высокого порядка .Эта ссылка определяет это как:

Функция более высокого порядка - это функция, которая может принимать другую функцию в качестве аргумента или которая возвращает функцию в качестве результата.

Обычно это делается для того, чтобы уменьшить количество повторений и сделать ваше приложение более компонуемым, чтобы уменьшить объем кода, который необходимо написать.Используя эту философию, мы можем еще больше улучшить код вышеВместо того, чтобы извлекать состояние и передавать его в функцию диспетчера, мы можем предоставить функцию, которая извлекает состояние и возвращает функцию, чтобы этот код мог выполняться много раз (поскольку мы можем удерживать ссылку на эту возвращенную функцию).

import Rx from 'rxjs/Rx';

const inputEl = document.querySelector('input');
const activeEl = document.querySelector('#active');
const doneEl = document.querySelector('done');

const appState = new Rx.BehaviorSubject({todos: []});

appState.subscribe(console.log);

//const dispatcher = fn => (...args) => appState.next(fn(...args));
//const actionX = dispatcher(data => ({type: 'X', data}));

const dispatcher = function (fn) {
    return function () {
        // arguments are the parameters passed to the function
        const result = fn.apply(null, arguments);
        return appState.next(result);
    };
};

const actionX = dispatcher(function (data) {
    return {type: 'X', data: data});
});

actionX('some data');

Используя современный JS для упрощения всего этого кода, вы получите то, что у вас было:

import Rx from 'rxjs/Rx';

const inputEl = document.querySelector('input');
const activeEl = document.querySelector('#active');
const doneEl = document.querySelector('done');

const appState = new Rx.BehaviorSubject({todos: []});

appState.subscribe(console.log);

const dispatcher = fn => (...args) => appState.next(fn(...args));
//const dispatcher = function (fn) {
//    return function () {
//        // arguments are the parameters passed to the function
//        const result = fn.apply(null, arguments);
//        return appState.next(result);
//    };
//};

const actionX = dispatcher(data => ({type: 'X', data}));
//const actionX = dispatcher(function (data) {
//    return {type: 'X', data: data});
//});

actionX('some data');
0 голосов
/ 24 апреля 2018

Это будет код после удаления структуры метода коротких рук,

function foo1(data){
  return {type: 'X', data}
}
function dispatcher(fn){    //fn = {type:'X', data}
  function foo2(...args){
    return appState.next(fn(...args));
  };
  return foo2;
}
const actionX = dispatcher(foo1);

actionX('something')'

Надеюсь, это поможет вам лучше понять.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...