1 module dpromise.async; 2 3 import dpromise.promise; 4 5 import core.thread : Fiber; 6 import std.concurrency : Generator, yield; 7 import std.traits; 8 9 Promise!T async(T)(T delegate() dg) nothrow if(!is(Unqual!T : Exception) && !is(Unqual!T : Promise!K, K)) 10 in { 11 assert(dg !is null); 12 }body { return promise!T((res, rej) { 13 static if(!is(T == void)) T value; 14 15 auto gen = new Generator!Awaiter({ 16 static if(!is(T == void)) { 17 value = dg(); 18 }else { 19 dg(); 20 } 21 }); 22 23 void inner() { 24 if(gen.empty) { 25 static if(!is(T == void)) { 26 res(value); 27 }else { 28 res(); 29 } 30 }else { 31 gen.front.then(() { 32 gen.popFront; 33 inner(); 34 }, (e){ 35 rej(e); 36 }); 37 } 38 } 39 inner(); 40 });} 41 42 43 T await(T)(Promise!T promise) 44 in { 45 bool inAsyncFunction() { 46 return (cast(Generator!Awaiter)Fiber.getThis) !is null; 47 } 48 assert(inAsyncFunction); 49 }body { 50 51 yield(cast(Awaiter)promise); 52 53 if(promise.isFulfilled) { 54 static if(!is(T == void)) return promise.value; 55 }else if(promise.isRejected) { 56 throw promise.exception; 57 }else { 58 assert(0); 59 } 60 }