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

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

Я понимаю, что некоторые экземпляры промежуточного программного обеспечения возвращают вещи (например, redux-promise) , и я понимаю, что другое промежуточное программное обеспечение (например, logging) не возвращает - и просто возвращает результат next(action).

Моя проблема заключается в том, что произойдет, если я захочу использовать две части промежуточного программного обеспечения, которые оба возвращают данные - наверняка они будут сбивать друг друга, и я получу возвращаемое значение только самого внешнего промежуточного программного обеспечения.

express/connect промежуточное программное обеспечение решает эту проблему, позволяя промежуточному программному обеспечению записывать свои «результаты» в объекты req и res, но каково решение с избыточностью?

ИЗМЕНИТЬ

Вот более конкретный пример моей проблемы:

У меня есть две части промежуточного программного обеспечения:

  1. ПО промежуточного слоя, которое откладывает выполнение всех действий на 3 секунды. Это промежуточное ПО возвращает функцию, которую можно вызвать для отмены отправки.
  2. Промежуточное ПО, которое возвращает число 5, потому что мне нужно число 5 по какой-то причине.

В зависимости от порядка, в котором я связываю эти два бита промежуточного программного обеспечения, результатом моего dispatch(action) будет либо отмена отсрочки fn, либо число 5. Но как мне получить оба этих результата?


person maambmb    schedule 07.03.2017    source источник
comment
Примерно так устроено промежуточное ПО Redux. Большинство промежуточных программ просто возвращают любое возвращаемое значение, которое они получают от next(), но промежуточным программам полностью разрешено возвращать что-то еще, если они этого хотят. Это в значительной степени сводится к тому, что функции JS возвращают только одно значение.   -  person markerikson    schedule 08.03.2017
comment
Путь к хорошему ответу может начаться с определений Redux Typescript: github. com/reactjs/redux/blob/master/index.d.ts   -  person contrebis    schedule 10.04.2018
comment
Для справки, это комментарий в комментариях Redux, в котором упоминается поведение произвольного возвращаемого значения, кстати: " rel="nofollow noreferrer">github.com/reduxjs/redux/blob/   -  person Venryx    schedule 24.10.2019


Ответы (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 );
person maambmb    schedule 07.03.2017

Взгляните на документацию по applyMiddleware. В нем объясняется, что промежуточное программное обеспечение должно быть компонуемым, чтобы его можно было подключить к цепочке промежуточного программного обеспечения, не беспокоясь о промежуточном программном обеспечении, которое применяется до и после него:

Ключевой особенностью промежуточного программного обеспечения является его компонуемость. Несколько промежуточных программ могут быть объединены вместе, где каждое промежуточное ПО не требует знания того, что идет до или после него в цепочке.

Документация очень хорошо объясняет аргументы, которые должны быть переданы промежуточному программному обеспечению, и ожидаемый результат.

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

person Yo Wakita    schedule 07.03.2017
comment
Привет Йо, спасибо за ответ! Прочитал связанную страницу, но все еще чувствую, что моя проблема осталась без ответа. Я отредактировал свой исходный вопрос, чтобы предоставить конкретный пример для повышения ясности. Спасибо! - person maambmb; 07.03.2017
comment
Я не уверен, что понимаю ваши примеры. Ожидается, что промежуточное ПО будет принимать два аргумента, getState и dispatch, и возвращать функцию, которая возвращает next(action). Сигнатура промежуточного программного обеспечения одинакова для каждого промежуточного программного обеспечения, поэтому у вас не будет промежуточного программного обеспечения, которое возвращает 5. Из документа: подпись промежуточного программного обеспечения ({ getState, dispatch }) => next => action - person Yo Wakita; 07.03.2017
comment
@YoWakita Я думаю, что maambmb имеет в виду тот же произвольный возврат, который упоминается в комментарии Redux здесь: rel="nofollow noreferrer">github.com/reduxjs/redux/blob/ - person Venryx; 24.10.2019

Вы упускаете смысл промежуточного программного обеспечения, его конвейера для потребления и отправки действий. Возвращаемые значения обычно игнорируются.

person John Little    schedule 16.07.2020