等待多个 ipc 调用完成,然后再继续电子/冗余

Waiting for multiple ipc calls to complete before continuing in electron/redux

本文关键字:再继续 然后 冗余 ipc 调用 等待      更新时间:2023-09-26

我正在开发一个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)是动作创建者,最后化简器会将响应保存在商店中。

store.dispatch(fetchStats())之后,我想立即调度另一个操作,以根据加载到存储中的值进行一些计算。但是,此操作通常会在 ipc 的响应到达之前发送。

我发现这个讨论有类似的问题,但他们使用 fetch 而不是 ipc 消息进行 api 调用,我不知道如何将他们的想法应用于我的问题。

所以我的问题来了:如何让程序在继续之前等待所有渠道的响应?

编辑:当我在 ipc 调用后为调度设置长度为 0 的超时时,它至少适用于即时响应,但当然,当响应需要更长的时间时,它无济于事。

store.dispatch(fetchOptions());
store.dispatch(fetchRequirements());
store.dispatch(fetchStats());
setTimeout(function() {
    store.dispatch(calculateThis());
    store.dispatch(calculateThat());
}, 0);

使用承诺的示例

假设

我不熟悉您的icpRenderer是如何工作的,也不熟悉调度何时完成。我将假设调度在呼叫dispatch(receiveOptions(arg))返回后完成

    ipcRenderer.on('sendOptions', function(event, arg) {
        dispatch(receiveOptions(arg));
    });

如果dispatch()是异步的,这将不起作用(除非您等到dispatch()完成后再解决承诺)。

如果我的假设是正确的

您应该能够返回收到这样的"承诺"(并解决它)

    // 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

(请注意,你可以在不传递"promise"的情况下调用fetchOptions,因为我们只在promise存在时才调用promise.resolve()。因此,这不应该使现有代码复杂化。

为了等待承诺解决,你可以这样做

    // 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.
        );
    },

代码不是很干净,但希望它至少可以工作。