在 electron/redux 中继续之前等待多个 ipc 调用完成
Waiting for multiple ipc calls to complete before continuing in electron/redux
我正在使用 Electron、React 和 Redux 开发应用程序。在程序启动时,我在渲染进程和主进程之间进行了一些异步 ipc 调用,并将结果保存在商店中。
// in the main app component
componentWillMount() {
const { store } = this.context;
store.dispatch(fetchOptions());
store.dispatch(fetchRequirements());
store.dispatch(fetchStats());
/* miracle function */
},
// actions.js
export function fetchOptions() {
return dispatch => {
dispatch(requestOptions());
ipcRenderer.on('sendOptions', function(event, arg) {
dispatch(receiveOptions(arg));
});
ipcRenderer.send('requestOptions', '');
};
}
// others accordingly
receiveOptions(arg)
、receiveRequirements(arg)
和 receiveStats(arg)
是 action creator,最终 reducer 会将响应保存在 store 中。
紧接在 store.dispatch(fetchStats())
之后,我想分派另一个操作以根据加载到存储中的值进行一些计算。但是,此操作通常会在 ipc 的响应到达之前分派。
我发现 this discussion 有类似的问题,但他们使用 fetch
而不是 ipc 消息进行 api 调用,我不知道如何将他们的想法应用到我的问题。
所以这是我的问题:如何让程序在继续之前等待所有通道的响应?
编辑:当我在 ipc 调用后为调度设置一个超出长度 0 的时间时,它至少适用于立即响应,但是当响应花费更长的时间时它当然没有帮助。
store.dispatch(fetchOptions());
store.dispatch(fetchRequirements());
store.dispatch(fetchStats());
setTimeout(function() {
store.dispatch(calculateThis());
store.dispatch(calculateThat());
}, 0);
使用 Promises
的示例
假设
我不熟悉你的 icpRenderer
是如何工作的,也不熟悉调度完成时的具体情况。我将假设调度在dispatch(receiveOptions(arg))
returns in
调用后完成
ipcRenderer.on('sendOptions', function(event, arg) {
dispatch(receiveOptions(arg));
});
如果 dispatch()
是异步的,这将不起作用(除非你等到 dispatch()
完成后才解决承诺)。
如果我的假设是正确的
你应该能够 return 收到这样的“承诺”(并解决它)
// actions.js
export function fetchOptions(promise) {
return dispatch => {
dispatch(requestOptions());
ipcRenderer.on('sendOptions', function(event, arg) {
dispatch(receiveOptions(arg));
if (promise) promise.resolve(); // Resolve the promise
});
ipcRenderer.send('requestOptions', '');
}
}
// return Promises others accordingly
(请注意,您可以在不传递“承诺”的情况下调用 fetchOptions,因为我们仅在存在承诺时调用 promise.resolve()。因此,这不会使您现有的代码复杂化。)
为了等待promise解决,可以这样做
// in the main app component
componentWillMount() {
const { store } = this.context;
const promises = [
new Promise((resolve, reject) =>
store.dispatch(fetchOptions({resolve, reject}))),
new Promise((resolve, reject) =>
store.dispatch(fetchRequirements({resolve, reject}))),
new Promise((resolve, reject) =>
store.dispatch(fetchStats({resolve, reject})))
];
Promise.all(promises).then(() =>
// Dispatch another action after the first three dispatches are completed.
);
},
代码并没有变得非常干净,但希望它至少可以工作。
我正在使用 Electron、React 和 Redux 开发应用程序。在程序启动时,我在渲染进程和主进程之间进行了一些异步 ipc 调用,并将结果保存在商店中。
// in the main app component
componentWillMount() {
const { store } = this.context;
store.dispatch(fetchOptions());
store.dispatch(fetchRequirements());
store.dispatch(fetchStats());
/* miracle function */
},
// actions.js
export function fetchOptions() {
return dispatch => {
dispatch(requestOptions());
ipcRenderer.on('sendOptions', function(event, arg) {
dispatch(receiveOptions(arg));
});
ipcRenderer.send('requestOptions', '');
};
}
// others accordingly
receiveOptions(arg)
、receiveRequirements(arg)
和 receiveStats(arg)
是 action creator,最终 reducer 会将响应保存在 store 中。
紧接在 store.dispatch(fetchStats())
之后,我想分派另一个操作以根据加载到存储中的值进行一些计算。但是,此操作通常会在 ipc 的响应到达之前分派。
我发现 this discussion 有类似的问题,但他们使用 fetch
而不是 ipc 消息进行 api 调用,我不知道如何将他们的想法应用到我的问题。
所以这是我的问题:如何让程序在继续之前等待所有通道的响应?
编辑:当我在 ipc 调用后为调度设置一个超出长度 0 的时间时,它至少适用于立即响应,但是当响应花费更长的时间时它当然没有帮助。
store.dispatch(fetchOptions());
store.dispatch(fetchRequirements());
store.dispatch(fetchStats());
setTimeout(function() {
store.dispatch(calculateThis());
store.dispatch(calculateThat());
}, 0);
使用 Promises
的示例假设
我不熟悉你的 icpRenderer
是如何工作的,也不熟悉调度完成时的具体情况。我将假设调度在dispatch(receiveOptions(arg))
returns in
ipcRenderer.on('sendOptions', function(event, arg) {
dispatch(receiveOptions(arg));
});
如果 dispatch()
是异步的,这将不起作用(除非你等到 dispatch()
完成后才解决承诺)。
如果我的假设是正确的
你应该能够 return 收到这样的“承诺”(并解决它)
// actions.js
export function fetchOptions(promise) {
return dispatch => {
dispatch(requestOptions());
ipcRenderer.on('sendOptions', function(event, arg) {
dispatch(receiveOptions(arg));
if (promise) promise.resolve(); // Resolve the promise
});
ipcRenderer.send('requestOptions', '');
}
}
// return Promises others accordingly
(请注意,您可以在不传递“承诺”的情况下调用 fetchOptions,因为我们仅在存在承诺时调用 promise.resolve()。因此,这不会使您现有的代码复杂化。)
为了等待promise解决,可以这样做
// in the main app component
componentWillMount() {
const { store } = this.context;
const promises = [
new Promise((resolve, reject) =>
store.dispatch(fetchOptions({resolve, reject}))),
new Promise((resolve, reject) =>
store.dispatch(fetchRequirements({resolve, reject}))),
new Promise((resolve, reject) =>
store.dispatch(fetchStats({resolve, reject})))
];
Promise.all(promises).then(() =>
// Dispatch another action after the first three dispatches are completed.
);
},
代码并没有变得非常干净,但希望它至少可以工作。