Awaiting a result from another task

I'm new to Swift and async/await; I'd like to know if there is a clean way to pass a single value between Tasks in async/await.

As an example motivating use case of what I mean: imagine that I have some protocol that can async send and receive messages in some shared stream. In the message protocol, I can set a message ID on the request, and when a response comes back with the same message ID, I want to asynchronously deliver it. A simple unary RPC.

What I have today looks like this:

func rpc(_ req: Request) async throws -> Response {
    return try await withCheckedThrowingContinuation { continuation in
        Task {
            let msgID = await self.wantResponses.store(continuation)
            req.msgID = msgID
            await self.send(req)
        }
    }
}

...where some other Task is reading the messages from the stream, matching them up with the continuations stored in wantResponses, and calling .resume(returning: resp).

This works, but it feels very awkward. I'm having to nest my logic 2-levels deep because withCheckedThrowingContinuation takes a closure, and because that closure doesn't itself run in an async context.

What I'd really like is something akin to a Future, but async/await native and without the closure.

E.g.

func rpc(_ req: Request) async throws -> Response {
    let future = AsyncFuture<Response, Error>()
    let msgID = await self.wantResponses.store(future.continuation)
    req.msgID = msgID
    await self.send(req)
    return try await future.value
}

Does anything like this exist?

I'm really struggling to figure out a good way to use async/await if the thing that produces a result is in a different Task that is not a direct child of the thing that wants to await for that result.