         
         let asyncItemTransformer = { (item: String, completion: @escaping (String) -> Void) in
             // fake out a process which takes 'item' and asynchronously gets a result for it
-            DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + .seconds(Int.random(in: 0 ... 3))) { // use random delay to ensure results map to correct items even if results are received out of (collection) order
+            DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + .milliseconds(Int.random(in: 0 ... 500))) { // use random delay to ensure results map to correct items even if results are received out of (collection) order
                 let resultForItem = "\(item) result"
                 completion(resultForItem)
             }


        let asyncItemBlock = { (item: String, completion: @escaping () -> Void) in
            // fake out a process which takes 'item' and asynchronously performs a block with it
            DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + .seconds(Int.random(in: 0 ... 3))) { // use random delay to more closely simulate read async usage
                results.insert(item)
                completion()
            }

        
        let asyncItemTransformer = { (item: String, completion: @escaping (String?) -> Void) in
            // fake out a process which takes 'item' and asynchronously gets a result for it
            DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + .milliseconds(Int.random(in: 0 ... 500))) { // use random delay to ensure results map to correct items even if results are received out of (collection) order
                guard item != "MAP_TO_NIL" else { // fake out getting nil for some items
                    completion(nil)
                    return
