10

所以我刚刚阅读了 redux 中间件,听起来很棒。不过有一件事让我很烦——中间件的返回值。

我知道中间件的某些实例返回东西(即redux-promise),而我得到其他中间件(即logging)没有 - 并且只是返回next(action).

我的问题是,如果我想使用两个都返回东西的中间件会发生什么——它们肯定会互相破坏,我只会得到最外层中间件的返回值。

express/connect中间件通过让中间件将其“结果”写入reqres对象来解决这个问题,但是 redux 的解决方案是什么?

编辑

这是我的问题的更具体示例:

我有两个中间件:

  1. 将所有操作延迟 3 秒分派的中间件。这个中间件返回一个函数,可以调用它来取消调度
  2. 返回数字 5 的中间件,因为出于某种原因我需要数字 5。

根据我链接这两个中间件的顺序,my 的结果dispatch(action)要么是延迟取消 fn,要么是数字 5。但是我如何获得这两个结果呢?

4

3 回答 3

3

所以下面是一个可运行的脚本,它演示了我正在尝试(并且失败)描述的问题。它还包括一个潜在的解决方案(使用中间件包装器)。很想知道是否有更优雅的解决方案......

var { createStore, applyMiddleware } = require( "redux" );
var dispatchResult;

// create the results object to be passed along the middleware chain, collecting
// results as it goes
const genesis = _store => next => action => {
    next( action );
    return {};
};

const wrapper = ( key, mware ) => store => next => action => {

    // extract the results object by storing the result of next(action)
    // when it is called within the middleware
    var extractedResult;
    function modifiedNext( action ) {
        extractedResult = next( action );
        return extractedResult;
    }

    // get the result of this middleware and append it to the results object
    // then pass on said results object...
    var newResult = mware( store )( modifiedNext )( action );
    extractedResult[ key ] = newResult;
    return extractedResult;
};

// create standard logging middleware
const logger = store => next => action => {
    let result = next( action );
    console.log( `value is: ${ store.getState() }.`);
    return result;
};

// create middleware that returns a number
const gimme = val => _store => next => action => {
    next( action );
    return val;
};

// create our super simple counter incrementer reduer
function reducer( state = 0, action ) {
    if( action.type === "INC" )
        return state + 1;
    return state;
}


// first lets try running this without the wrapper:
dispatchResult = createStore( reducer, applyMiddleware(
    gimme( 4 ),
    logger,
    gimme( 5 )
) ).dispatch( { type : "INC" } );

// will return only 4 (the result of the outermost middleware)
// we have lost the 5 from the gimme(5) middleware
console.log( dispatchResult );

// now we include the middleware wrapper and genesis middleware
dispatchResult = createStore( reducer, applyMiddleware(
    wrapper( "g4", gimme( 4 ) ),
    logger,
    wrapper( "g5", gimme( 5 ) ),
    genesis
) ).dispatch( { type : "INC" } );

// we will now return { g4 : 4, g5 : 5 }
// we have preserved the results of both middlewares
console.log( dispatchResult );
于 2017-03-07T22:08:09.233 回答
3

查看有关applyMiddleware. 它解释了中间件将被编写成可组合的,这样它就可以插入到中间件链中,而不必担心在它之前和之后应用的中间件:

中间件的关键特性是它是可组合的。多个中间件可以组合在一起,其中每个中间件不需要知道链中它之前或之后的内容。

该文档很好地解释了要传递到中间件的参数和预期的回报。

https://redux.js.org/api/applyMiddleware

于 2017-03-07T20:27:39.860 回答
0

您错过了中间件的要点,它是用于消费和调度操作的管道。返回值通常被忽略。

于 2020-07-16T23:56:46.433 回答