【问题标题】:How can processing in a Promise be triggered before it is needed to be resolved, like a java Future?如何在需要解决之前触发 Promise 中的处理,例如 java Future?
【发布时间】:2023-03-11 09:58:02
【问题描述】:

我有一个用 Mocha 编写的集成测试,需要在其他事情发生之前注册一个侦听器,否则我最终会遇到竞争条件。

基本上,我正在向某个 HTTP 服务器发送一个帖子,然后期待来自 Kafka 消息传递服务的回调,其中包含一些我需要检查其值的消息。 (发到http服务器的帖子就是把消息放到kafka上)。

我的初始剪辑在比赛条件下结束。

var request = require("supertest-as-promised");
var Promise = require("bluebird");

beforeEach() { //set up kafka connection and kafkaConsumer ... }
describe('send-status', function statusSend() {
    it("sends a post to the server and gets a message on kafka", function (done) {
           request('http://myserver:8080')
                    .post('/myendpoint')
                    .type('json')
                    .send(stuff)
                    .expect(200)
            })
            .then(function () {
                //todo:  antipattern - can be replaced with a custom promisfier.
                return new Promise(function (resolve, reject) {
                    kafkaConsumer.on('message', function (message) {
                            resolve(message)
                        })
                        //and reject cases
                });
            })
            .then(function (message) {
                //check message
                done()
             })
            .catch() ...

问题当然是 kafka 消息可以在发布后立即被触发,但在第二个承诺可以注册 kafkaConsumer.on('message') 侦听器之前。

所以我需要在链中开始发布请求承诺之前注册kafkaConsumer.on('message')

这就是我对节点和承诺的认识分崩离析的地方。如果这是 Java,我会创建一个 Callable 来启动监听器(并且可能有一个闩锁等到它在我的帖子之前启动),将它扔给一个执行器并稍后使用那个未来 - 值可能已经存在或者未来会等待它。

有了 Promise,我不明白如何在 then() 在链中被调用之前启动 kafkaConsumer.on('message')

我尝试过这样的事情,但它很丑陋并且仍然会导致竞争状况:

function foo(message) {
    return new Promise(function (resolve, reject) {
        resolve(message);
    });
}
describe(...)
    it("sends post to ...", function(done) {
        var onMessagePromise;
        kafkaConsumer.on('message', function (message) {
            onMessagePromise = foo(message)
        });

        request()
        .then(function () {
            return onMessagePromise;
        })
        .then ...

我的另一个想法是在发出请求之前监听消息,将其分配给一个变量,然后让 promise 解析该变量......但如果消息在 promise 之后出现,这将不起作用回来和善良打败了这一点。我能想到的一切都会导致竞争条件。

【问题讨论】:

    标签: javascript node.js promise mocha.js


    【解决方案1】:

    所以我需要在链中开始发布请求承诺之前注册kafkaConsumer.on('message')

    您可以这样做,从您的解释来看,这听起来与在 Java 中的解决方式非常相似(尽管我对 Java 不太了解,所以我相信会是 一些 em> 差异):

    var kafkaPromise = new Promise(function (resolve, reject) {
      kafkaConsumer.on('message', function (message) {
        resolve(message);
      })
      //and reject cases
    });
    
    request('http://myserver:8080')
            .post('/myendpoint')
            .type('json')
            .send(stuff)
            .expect(200)
            .then(function() {
              return kafkaPromise;
            })
            .then(...)
            .catch(...);
    

    如果kafkaPromise被解析,则使用它的值;如果它仍然处于未决状态,则链将等到它得到解决(或被拒绝)后再继续。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-27
      • 1970-01-01
      • 2019-02-27
      • 2017-09-24
      • 2019-05-28
      • 1970-01-01
      • 2021-05-01
      • 2022-01-20
      相关资源
      最近更新 更多