请求基本的Typescript / Javascript和RxJs代码说明

时间:2018-04-24 17:19:15

标签: javascript typescript rxjs

我正在学习rxjs,并且很难绕过这两行代码:

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

至少部分我不明白的原因是它使用的是我还不习惯的速记语法。我一直在努力扩展它,以确切了解发生了什么,但避风港能够正确地做到这一点。例如,actionX调用dispatcher并且函数作为参数传递,但实际上是否运行直到在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 :(得分:1)

一旦删除了简写方法结构,这将是代码

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

希望这能让你更好地理解。

答案 1 :(得分:1)

没有arrow functions=>),rest parameters...args) => {})和spread syntaxappState.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中的下一个值。如果没有这个,你需要记住每次都将你的值从回调推回到你的app状态。

换句话说,不使用此模式,上面的代码将是:

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

在函数式编程中,有higher order functions的概念。该链接将其定义为:

  

高阶函数是一个函数,可以将另一个函数作为参数,或者返回一个函数作为结果。

这通常是为了减少重复并使您的应用程序更具可组合性,以减少需要编写的代码。使用这种理念,我们可以进一步改进上面的代码。我们可以提供一个检索状态并返回一个函数的函数,而不必检索状态并将其传递给调度程序函数,这样就可以多次执行此代码(因为我们可以保留对返回函数的引用)

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