Redux中间件设计re:返回值

时间:2017-03-07 20:13:45

标签: javascript redux middleware redux-promise

所以我刚刚阅读了redux中间件,听起来很棒。但有一件事就是让我烦恼 - 中间件的返回值。

我理解中间件的一些实例返回内容(即redux-promise),而我得到的其他中间件(即logging)不会 - 并且只返回{{1的结果}}

我的问题是如果我想使用两个都返回内容的中间件会发生什么 - 当然它们会互相破坏,我只能获得最外层中间件的返回值。

next(action)中间件通过让中间件写出"结果"来解决这个问题。对express/connectreq对象,但是有什么解决方案与redux?

修改

以下是我的问题的一个更具体的例子:

我有两件中间件:

  1. 推迟3秒钟发送的所有操作的中间件。此中间件返回一个可以调用以取消调度的函数
  2. 返回数字5的中间件,因为我出于某种原因需要数字5.
  3. 根据我将这两个中间件链接的顺序,我的res的结果将是延迟取消fn或数字5.但我如何得到这两个结果?

4 个答案:

答案 0 :(得分:2)

查看applyMiddleware上的文档。它解释说中间件应该被编写为可组合的,这样它就可以插入到中间件链中,而不必担心在它之前和之后应用的中间件:

  

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

该文档非常好地解释了要传递给中间件的参数和预期的返回。

http://redux.js.org/docs/api/applyMiddleware.html

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:-1)

在阅读了你的例子之后,我认为你不理解中间件的滚动,事实上你做了一个通常你必须在动作创建者或你在中间件中做的减速器中进行处理。

  

虽然中间件可用于各种事物,包括   异步API调用,您理解这一点非常重要   它来自哪里。我们将引导您完成思考过程   通过使用日志记录和崩溃报告来导致中间件   实例

http://redux.js.org/docs/advanced/Middleware.html