Как вы можете видеть в в middleware example, есть несколько элементов промежуточного слоя, которые создают трубу:
rafScheduler -> timeoutScheduler -> thunk -> vanillaPromise -> etc...
Действие перемещается все элементы промежуточного слоя перед тем, как к базовому редукторе или перехвата одной из элементы промежуточного слоя. Каждый элемент промежуточного программного обеспечения может принять решение о переносе действия на следующее промежуточное программное обеспечение в цепочке с помощью next()
. Тем не менее, иногда мы хотим, чтобы действие двигало цепь с самого начала.
Например, с помощью redux thunk мы отправляем асинхронное действие, которое будет обрабатываться промежуточным программным обеспечением thunk. Асинхронное действие отправит другое действие, когда асинхронный вызов завершится успешно. Это действие должно начинаться снова с промежуточного программного обеспечения rafScheduler
.
Если диспетчер работал бы следующим образом, он вместо этого отправился бы к промежуточному программному обеспечению vanillaPromise
. Чтобы решить это, dispatch(action)
, независимо от того, где он был вызван, всегда отправляет цепочку с самого начала.
Чтобы создать такое поведение applyMiddleware()
пробегает промежуточный store => next => action
методы, передает middlewareAPI
апи к store
парам, проходит, и отменяет store.dispatch
с новой отправкой, который является combined промежуточным программным обеспечением. Здесь происходит волшебство - новая отправка - это цепочка методов промежуточного программного обеспечения, где каждый вызывает один после него при следующем вызове (следующий = следующий метод промежуточного слоя), а последние next()
- это старый store.dispatch
, который вызывает базовую редуктор:
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
var store = createStore(reducer, preloadedState, enhancer)
var dispatch = store.dispatch // this is the original dispatch
var chain = []
/*** this the store param of the middleware ***/
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
/*** store param is applied to old middlewares to create the chain ***/
chain = middlewares.map(middleware => middleware(middlewareAPI))
/*** The chain is composed. For all methods in the chain, but the last, next() is the middleware method after it in the chain, the last next is store.dispatch ***/
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch // the new dispatch is returned instead of the old
}
}
}
Что вы имеете в виду: «Каждый элемент промежуточного программного обеспечения может решить перенести действие на следующее промежуточное ПО в цепочке с помощью next()»? Я думал, что следующий относится к отправке из предыдущего промежуточного программного обеспечения? он используется как указатель на предыдущую отправку, поскольку используемые документы «let next = store.dispatch» – mangocaptain
Документы относятся к одному промежуточному программному обеспечению, а не к цепочке из них. В сложенной цепочке 'next()' относится к методу промежуточного программного обеспечения, который является одним после текущего элемента в цепочке. Только последняя следующая на самом деле 'store.dispatch'. –
@OriDrori не могли бы вы взглянуть на http://stackoverflow.com/questions/42217369/custom-redux-middleware-dispatch-to-beginning-of-middleware-chain? –