@@ -6,6 +6,40 @@ func someAsyncFunc() async -> String { "" }
66struct MyError : Error { }
77func someThrowingAsyncFunc( ) async throws -> String { throw MyError ( ) }
88
9+ // ==== Unsafe Continuations ---------------------------------------------------
10+
11+ struct Vegetable { }
12+
13+ func buyVegetables(
14+ shoppingList: [ String ] ,
15+ // a) if all veggies were in store, this is invoked *exactly-once*
16+ onGotAllVegetables: ( [ Vegetable ] ) -> ( ) ,
17+
18+ // b) if not all veggies were in store, invoked one by one (one or more times)
19+ onGotVegetable: ( Vegetable ) -> ( ) ,
20+ // b) if at least one onGotVegetable was called *exactly-once*
21+ // this is invoked once no more veggies will be emitted
22+ onNoMoreVegetables: ( ) -> ( ) ,
23+ // c) if no veggies _at all_ were available, this is invoked *exactly once*
24+ onNoVegetablesInStore: ( Error ) -> ( )
25+ ) { }
26+
27+ // returns 1 or more vegetables or throws an error
28+ func buyVegetables( shoppingList: [ String ] ) async throws -> [ Vegetable ] {
29+ await try Task . withUnsafeThrowingContinuation { continuation in
30+ var veggies : [ Vegetable ] = [ ]
31+
32+ buyVegetables (
33+ shoppingList: shoppingList,
34+ onGotAllVegetables: { veggies in continuation. resume ( returning: veggies) } ,
35+ onGotVegetable: { v in veggies. append ( v) } ,
36+ onNoMoreVegetables: { continuation. resume ( returning: veggies) } ,
37+ onNoVegetablesInStore: { error in continuation. resume ( throwing: error) }
38+ )
39+ }
40+ }
41+
42+
943func test_unsafeContinuations( ) async {
1044 // the closure should not allow async operations;
1145 // after all: if you have async code, just call it directly, without the unsafe continuation
0 commit comments