在 Map 中存储承诺,以便以后解决/拒绝



我正在 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);
});
}

在承诺执行者之外的其他范围内调用resolve很少见,但消息传递是必要和标准做法的情况之一。顺便说一句,您可能需要考虑在响应接收上设置超时。

@Bergi有一个很好的答案。我有一个跟进任何人考虑做这样的事情:这是一个叫做"延迟/延迟"的概念,它曾经很热,但比异步/等待失宠了 - 查看本指南 https://codingbeautydev.com/blog/javascript-resolve-promise-from-outside/甚至这个库 https://www.npmjs.com/package/deferred

然后,您将在地图中存储一个可延期,在execute()中返回deferred.promise,并在您想要实际解决它时调用deffered.resolve()

最新更新