如何在需要解决之前触发 Promise 中的处理,例如 java Future?
How can processing in a Promise be triggered before it is needed to be resolved, like a java Future?
我有一个用 Mocha 编写的集成测试,需要在其他事情发生之前注册一个侦听器,否则我最终会遇到竞争条件。
基本上,我正在向某个 HTTP 服务器发送一个 post,然后期待来自 Kafka 消息服务的回调,其中包含一些我需要检查其值的消息。 (到 http 服务器的 post 正在将消息放在 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() ...
问题当然是可以在 post 之后立即触发 kafka 消息,但就在第二个承诺可以注册 kafkaConsumer.on('message')
侦听器之前。
所以我需要在链中启动 post 请求承诺之前注册 kafkaConsumer.on('message')
。
这就是我对 node 和 promises 的了解崩溃的地方。如果这是 Java,我会创建一个 Callable 来启动侦听器(并且可能有一个锁存器等待它在我的 post 之前启动),将其扔给执行程序并在以后使用那个未来 -该值要么已经存在,要么 Future 会等待它。
有了承诺,我不明白如何在链中调用 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 解析该变量......但是如果消息在诺言得到回报,善良打败了重点。我能想到的一切都会导致竞争条件。
So I need to register the kafkaConsumer.on('message')
before I start the post request promise in the chain.
你可以这样做,从你的解释来看,它听起来与 Java 中的解决方式非常相似(尽管我对 Java 了解不多,所以我肯定会有 一些 差异):
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
被解析,将使用它的值;如果它仍然悬而未决,链将等到它被解决(或拒绝)后再继续。
我有一个用 Mocha 编写的集成测试,需要在其他事情发生之前注册一个侦听器,否则我最终会遇到竞争条件。
基本上,我正在向某个 HTTP 服务器发送一个 post,然后期待来自 Kafka 消息服务的回调,其中包含一些我需要检查其值的消息。 (到 http 服务器的 post 正在将消息放在 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() ...
问题当然是可以在 post 之后立即触发 kafka 消息,但就在第二个承诺可以注册 kafkaConsumer.on('message')
侦听器之前。
所以我需要在链中启动 post 请求承诺之前注册 kafkaConsumer.on('message')
。
这就是我对 node 和 promises 的了解崩溃的地方。如果这是 Java,我会创建一个 Callable 来启动侦听器(并且可能有一个锁存器等待它在我的 post 之前启动),将其扔给执行程序并在以后使用那个未来 -该值要么已经存在,要么 Future 会等待它。
有了承诺,我不明白如何在链中调用 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 解析该变量......但是如果消息在诺言得到回报,善良打败了重点。我能想到的一切都会导致竞争条件。
So I need to register the
kafkaConsumer.on('message')
before I start the post request promise in the chain.
你可以这样做,从你的解释来看,它听起来与 Java 中的解决方式非常相似(尽管我对 Java 了解不多,所以我肯定会有 一些 差异):
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
被解析,将使用它的值;如果它仍然悬而未决,链将等到它被解决(或拒绝)后再继续。