问题
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