     ///
     /// - note: The resulting future is observed on the first future's queue.
     public static func zip<SecondValue>(_ lhs: Future<Value, Error>, _ rhs: Future<SecondValue, Error>) -> Future<(Value, SecondValue), Error> {
+        let future = Future<(Value, SecondValue), Error>(queue: lhs.queue)
+
         var firstValue: Value?
         var secondValue: SecondValue?
-        return Future<(Value, SecondValue), Error>(queue: lhs.queue) { succeed, fail in
-            func succeedIfPossible() {
-                // This is thread safe because both futures are observed on the
-                // same queue.
-                guard let firstValue = firstValue, let secondValue = secondValue else { return }
-                succeed((firstValue, secondValue))
-            }
-            lhs.on(success: { value in
-                firstValue = value
-                succeedIfPossible()
-            }, failure: fail) // whichever fails first
-
-            rhs.observeOn(lhs.queue).on(success: { value in
-                secondValue = value
-                succeedIfPossible()
-            }, failure: fail) // whichever fails first
-        }
+        func succeedIfPossible() {
+            // This is thread safe because both futures are observed on the
+            // same queue.
+            guard let firstValue = firstValue, let secondValue = secondValue else { return }
+            future.succeed((firstValue, secondValue))
+        }
+
+        lhs.observe(success: { value in
+            firstValue = value
+            succeedIfPossible()
+        }, failure: future.fail) // whichever fails first
+
+        // Use observeOn to make sure that both futures run on the same queue.
+        rhs.observeOn(lhs.queue).observe(success: { value in
+            secondValue = value
+            succeedIfPossible()
+        }, failure: future.fail) // whichever fails first
+
+        return future
     }
 
     /// Returns a future which succeedes when all of the given futures succeed.

        if queue === self.queue {
            return self // We're already on that queue
        }
        return Future(queue: queue) { succeed, fail in
            observe(success: succeed, failure: fail)
        }
    }

    // MARK: Map

    ///
    /// - returns: A future with a result of the future returned by the closure.
    public func flatMap<NewValue>(_ closure: @escaping (Value) -> Future<NewValue, Error>) -> Future<NewValue, Error> {
        let future = Future<NewValue, Error>(queue: queue)
        observe(success: { value in
            closure(value).cascade(future)
        }, failure: future.fail)
        return future
    }

    /// The closure executes asynchronously when the future fails.
