在KJ中通过组合承诺传递上下文



使用KJ库,我编写了一个小型TCP服务器,读取"PING"并回应"砰"的一声。我设法写出这样的承诺:

char buffer[4];
kj::Own<kj::AsyncIoStream> clientStream;
addr->listen()->accept()
.then([&buffer, &clientStream](kj::Own<kj::AsyncIoStream> stream) {
clientStream = kj::mv(stream);
return clientStream->tryRead(buffer, 4, 4);
}).then([&buffer, &clientStream](size_t read) {
KJ_LOG(INFO, kj::str("Received", read, " bytes: ", buffer));
return clientStream->write("PONG", 4);
}).wait(waitScope);

我必须将buffer排除在承诺之外,并传递对它的引用。这意味着buffer必须保持在范围内,直到最后一个承诺完成。这就是这里的情况,但如果不是这样,有没有解决办法呢?

同样的事情对于clientStream:我必须声明它之前,然后等待,直到我收到它从accept(),并在这一点移动到外面,并使用它的引用。

有更好的方法吗?比如一种将上下文从一个承诺传递到另一个承诺的方式,总是由承诺拥有,因此不必留在"外部"?

似乎你的问题是你的第二个lambda想要访问第一个lambda的范围,但是你组织事情的方式阻止了这一点。你已经解决了这个问题,只要在它们共享的全局变量中添加变量就可以了。范围。

相反,你可以把第二个lambda放在第一个lambda里面,像这样:

addr->listen()->accept()
.then([](kj::Own<kj::AsyncIoStream> stream) {
auto buffer = kj::heapArray<char>(4);
auto promise = stream->tryRead(buffer.begin(),4,4);
return promise.then([stream=kj::mv(stream), buffer=kj::mv(buffer)] (size_t read) mutable {
KJ_LOG(INFO, kj::str("Received", read, " bytes: ", buffer));
return stream->write("PONG", 4);
});
}).wait(waitScope);

最新更新