Store Promise in Map to resolve/reject later

孤街醉人 提交于 2021-01-07 01:21:16

问题


I'm working on IPC in NodeJS and want to be able to send a message to the parent process from the child and "wait" for the result. My idea was to keep track of all the send messages in a map that maps the unique message ID to a promise. Once the process.on('message`) has been called I lookup the promise by the ID I got back from the parent and want to resolve or reject the promise.

I came up with this, but am stuck at the resolve/reject part:

'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);
    }
}

Can someone push me in the right direction on how to solve this? Is this even possible and best-practice?

Thanks!


回答1:


You would not store the promise in the map. You would store only the resolver function to call later - the promise is created and returned immediately.

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);
    });
}

It is rare to call resolve in some other scope than the promise executor's, but messaging is one of those cases where it is necessary and the standard practice. Btw, you might want to consider putting a timeout on the response receival.



来源:https://stackoverflow.com/questions/61937887/store-promise-in-map-to-resolve-reject-later

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!