请求基本的打字稿/JavaScript和RXJS代码说明



我正在学习RXJS,并且在这两行代码周围缠绕我的头很难:

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

至少我不明白的部分原因是它正在使用我还不习惯的速记语法。我一直在尝试将其扩展,以确切了解正在发生的事情,但无法正确地做到这一点。例如,ActionX调用调度程序和函数作为paramater传递,但是直到在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"}

没有箭头功能(=>(,REST参数(...args) => {}(和扩展语法(appState.next(fn(...args))(的更经典JS方法:

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

这将是删除短手方法结构后的代码,

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')'

希望这能给您更好的理解。

最新更新