Implement async/await using Fiber
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Fri May 20 17:15:34 PDT 2016
On 05/20/2016 12:56 PM, Yuxuan Shui wrote:
> On Friday, 20 May 2016 at 06:40:42 UTC, Jacob Carlborg wrote:
>> On 2016-05-20 04:14, Yuxuan Shui wrote:
>>
>>> Hmm... This could work. But I'm not satisfied with this solution. What
>>> if I have multiple yield sites in the fiber, and each have different
>>> return types?
>>>
>>> Maybe I should use a Variant?
>>
>> I think you can view "yield" as a form of "return". If you cannot
>> return different types from a function (without it being a template)
>> it would be weird if you could yield different types.
>
> But this is yield as in coroutine, not yield as in generators. Those
> yields doesn't return value to the caller of the fiber.
>
> Let's have an example:
>
> void func() {
> string a = wait_for_user_input();
> int b = wait_for_user_to_click_a_button();
> }
>
> Those two wait()s could use yield internally to transfer execution back
> to the caller and wait for input. But it's difficult with current dlang
> fiber because there's no (elegant) way to pass data (preferably with
> different types) while transferring executing to/from fibers.
Agreed. Fibers are not a language construct.
One has to do what std.concurrency.Generator does internally. In this
case, we need another layer of function calls. (I could have used
Generator below and I could avoid creating a fiber for each call by
moving the fibers to module-scope.)
import core.thread;
void input_fiber(ref string input) {
while (true) {
input = "hello";
Fiber.yield();
}
}
string wait_for_user_input() {
string input;
auto f = new Fiber(() => input_fiber(input));
f.call();
return input;
}
void click_fiber(ref int button) {
while (true) {
button = 42;
Fiber.yield();
}
}
int wait_for_user_to_click_a_button() {
int button;
auto f = new Fiber(() => click_fiber(button));
f.call();
return button;
}
void func() {
foreach (i; 0 .. 10) {
string a = wait_for_user_input();
assert(a == "hello");
int b = wait_for_user_to_click_a_button();
assert(b == 42);
}
}
void main() {
func();
}
Ali
More information about the Digitalmars-d-learn
mailing list