将承诺存储在地图中以供以后解决/拒绝

2022-04-15 00:00:00 node.js message-queue javascript promise

我在NodeJS中的IPC上工作,希望能够从子进程向父进程发送消息并"等待"结果。我的想法是跟踪映射中的所有发送消息,该映射将唯一的消息ID映射到承诺。调用process.on('message`)后,我将根据从父级返回的ID查找承诺,并希望解析或拒绝该承诺。

我想出了这个,但我被解决/拒绝部分卡住了:

'use strict'

import RequestMessage from "../messages/request/RequestMessage";
import ResponseMessage from "../messages/response/ResponseMessage";

const process = require('process');

export class CommunicationManager {
    private messageQueue: Map<string, Promise<any>>;

    constructor() {
        this.messageQueue = new Map();

        process.on('message', (payload: any) => {
            if (payload.hasOwnProperty("_id")
                && this.messageQueue.has(payload.get("_id"))) {

                let promise = this.messageQueue.get(payload);
                // Resolve or reject the promise..

                this.messageQueue.delete(payload.get("_id"));
            } else {
                console.error(`Got unknown message from parent: ${payload}`);
            }
        });
    }

    public execute(message: RequestMessage): Promise<ResponseMessage> {
        process.send(message);
        this.messageQueue.set(message.id(), // a promise here);
    }
}

有人能在如何解决这个问题上把我推向正确的方向吗?这是可能的最佳实践吗?

谢谢!


解决方案

您不会将承诺存储在地图中。您将只存储稍后调用的解析器函数-承诺被创建并立即返回。

init() {
    process.on('message', (payload: any) => {
        if ("_id" in payload && this.messageQueue.has(payload._id)) {
            const resolve = this.messageQueue.get(payload._id);
            this.messageQueue.delete(payload._id);
            if (payload.isFulfilled) {
                resolve(payload.value);
            else {
                resolve(Promise.reject(payload.error));
            }
        } else {
            console.error(`Got unknown message from parent: ${payload}`);
        }
    });
}

public execute(message: RequestMessage): Promise<ResponseMessage> {
    return new Promise(resolve => {
        this.messageQueue.set(message.id(), resolve);
        process.send(message);
    });
}

在Promise Executor之外的其他作用域中调用resolve的情况很少,但消息传递是必要的情况之一,也是标准做法。顺便说一句,您可能需要考虑在响应接收上设置超时。

相关文章