wait-service.js (2024B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 "use strict"; 5 6 /** 7 * A middleware which acts like a service, because it is stateful 8 * and "long-running" in the background. It provides the ability 9 * for actions to install a function to be run once when a specific 10 * condition is met by an action coming through the system. Think of 11 * it as a thunk that blocks until the condition is met. Example: 12 * 13 * ```js 14 * const services = { WAIT_UNTIL: require('wait-service').NAME }; 15 * 16 * { type: services.WAIT_UNTIL, 17 * predicate: action => action.type === constants.ADD_ITEM, 18 * run: (dispatch, getState, action) => { 19 * // Do anything here. You only need to accept the arguments 20 * // if you need them. `action` is the action that satisfied 21 * // the predicate. 22 * } 23 * } 24 * ``` 25 */ 26 const NAME = (exports.NAME = "@@service/waitUntil"); 27 28 function waitUntilService({ dispatch, getState }) { 29 let pending = []; 30 31 function checkPending(action) { 32 const readyRequests = []; 33 const stillPending = []; 34 35 // Find the pending requests whose predicates are satisfied with 36 // this action. Wait to run the requests until after we update the 37 // pending queue because the request handler may synchronously 38 // dispatch again and run this service (that use case is 39 // completely valid). 40 for (const request of pending) { 41 if (request.predicate(action)) { 42 readyRequests.push(request); 43 } else { 44 stillPending.push(request); 45 } 46 } 47 48 pending = stillPending; 49 for (const request of readyRequests) { 50 request.run(dispatch, getState, action); 51 } 52 } 53 54 return next => action => { 55 if (action.type === NAME) { 56 pending.push(action); 57 return null; 58 } 59 const result = next(action); 60 checkPending(action); 61 return result; 62 }; 63 } 64 exports.waitUntilService = waitUntilService;