You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
3.1 KiB
92 lines
3.1 KiB
//
|
|
// Promise+Then.swift
|
|
// then
|
|
//
|
|
// Created by Sacha Durand Saint Omer on 20/02/2017.
|
|
// Copyright © 2017 s4cha. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public extension Promise {
|
|
|
|
@discardableResult public func then<X>(_ block: @escaping (T) -> X) -> Promise<X> {
|
|
let p = registerThen(block)
|
|
tryStartInitialPromiseAndStartIfneeded()
|
|
return p
|
|
}
|
|
|
|
@discardableResult public func registerThen<X>(_ block: @escaping (T) -> X) -> Promise<X> {
|
|
let p = Promise<X>()
|
|
|
|
synchronize { state, blocks in
|
|
switch state {
|
|
case let .fulfilled(value):
|
|
let x: X = block(value)
|
|
p.fulfill(x)
|
|
case let .rejected(error):
|
|
p.reject(error)
|
|
case .dormant, .pending:
|
|
blocks.success.append({ t in
|
|
p.fulfill(block(t))
|
|
})
|
|
blocks.fail.append({ e in
|
|
p.reject(e)
|
|
})
|
|
blocks.progress.append({ f in
|
|
p.setProgress(f)
|
|
})
|
|
}
|
|
}
|
|
passAlongFirstPromiseStartFunctionAndStateTo(p)
|
|
return p
|
|
}
|
|
|
|
@discardableResult public func then<X>(_ block: @escaping (T) -> Promise<X>) -> Promise<X> {
|
|
tryStartInitialPromiseAndStartIfneeded()
|
|
return registerThen(block)
|
|
}
|
|
|
|
@discardableResult public func registerThen<X>(_ block: @escaping (T) -> Promise<X>)
|
|
-> Promise<X> {
|
|
let p = Promise<X>()
|
|
|
|
synchronize { state, blocks in
|
|
switch state {
|
|
case let .fulfilled(value):
|
|
registerNextPromise(block, result: value,
|
|
resolve: p.fulfill, reject: p.reject)
|
|
case let .rejected(error):
|
|
p.reject(error)
|
|
case .dormant, .pending:
|
|
blocks.success.append({ [weak self] t in
|
|
self?.registerNextPromise(block, result: t, resolve: p.fulfill,
|
|
reject: p.reject)
|
|
})
|
|
blocks.fail.append(p.reject)
|
|
blocks.progress.append(p.setProgress)
|
|
}
|
|
}
|
|
p.start()
|
|
passAlongFirstPromiseStartFunctionAndStateTo(p)
|
|
return p
|
|
}
|
|
|
|
@discardableResult public func then<X>(_ promise: Promise<X>) -> Promise<X> {
|
|
return then { _ in promise }
|
|
}
|
|
|
|
@discardableResult public func registerThen<X>(_ promise: Promise<X>) -> Promise<X> {
|
|
return registerThen { _ in promise }
|
|
}
|
|
|
|
fileprivate func registerNextPromise<X>(_ block: (T) -> Promise<X>,
|
|
result: T,
|
|
resolve: @escaping (X) -> Void,
|
|
reject: @escaping ((Error) -> Void)) {
|
|
let nextPromise: Promise<X> = block(result)
|
|
nextPromise.then { x in
|
|
resolve(x)
|
|
}.onError(reject)
|
|
}
|
|
}
|