SwiftTask 5.0.0

SwiftTask 5.0.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最新发布2016年6月
SPM支持 SPM

Yasuhiro Inami 维护。



SwiftTask 5.0.0

  • 作者:
  • Yasuhiro Inami

SwiftTask Circle CI

Promise + 进度 + 暂停 + 取消 + 重试,用于 Swift。

SwiftTask

安装方法

请参阅 ReactKit Wiki 页面

例子

基本

// define task
let task = Task<Float, String, NSError> { progress, fulfill, reject, configure in

    player.doSomethingWithProgress({ (progressValue: Float) in
        progress(progressValue) // optional
    }, completion: { (value: NSData?, error: NSError?) in
        if error == nil {
            fulfill("OK")
        }
        else {
            reject(error)
        }
    })

    // pause/resume/cancel configuration (optional)
    configure.pause = { [weak player] in
        player?.pause()
    }
    configure.resume = { [weak player] in
        player?.resume()
    }
    configure.cancel = { [weak player] in
        player?.cancel()
    }

}

// set success & failure
task.success { (value: String) -> Void in
    // do something with fulfilled value
}.failure { (error: NSError?, isCancelled: Bool) -> Void in
    // do something with rejected error
}

// you can call configured operations outside of Task-definition
task.pause()
task.resume()
task.cancel()

注意,player具有以下方法,可与SwiftTask很好地配合使用

  • doSomethingWithProgress(_:completion:)(进度回调为可选)
  • pause()(可选)
  • resume()(可选)
  • cancel()(可选)

一个最好的例子是Alamofire(网络库),如下所示。

使用Alamofire

typealias Progress = (bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
typealias AlamoFireTask = Task<Progress, String, NSError>

// define task
let task = AlamoFireTask { progress, fulfill, reject, configure in

    Alamofire.download(.GET, "http://httpbin.org/stream/100", destination: somewhere)
    .progress { bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in

        progress((bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) as Progress)

    }.response { request, response, data, error in

        if let error = error {
            reject(error)
            return
        }

        fulfill("OK")

    }

    return
}

// set progress & then
task.progress { (oldProgress: Progress?, newProgress: Progress) in

    println("\(newProgress.bytesWritten)")
    println("\(newProgress.totalBytesWritten)")
    println("\(newProgress.totalBytesExpectedToWrite)")

}.then { (value: String?, errorInfo: AlamoFireTask.ErrorInfo?) -> Void in
    // do something with fulfilled value or rejected errorInfo
}

可重试

Task可以通过使用retry()方法重试多次。例如,task.retry(n)如果task持续被拒绝,将最多重试n次(总尝试次数为n+1),而task.retry(0)显然与没有重试的task本身相同。

这个特性对于不稳定的任务非常有用,例如网络连接。通过在SwiftTask方面实现retryable,不再需要在player(内部逻辑)类中编写相似的代码。

task.retry(2).progress { ... }.success { ...
    // this closure will be called even when task is rejected for 1st & 2nd try
    // but finally fulfilled in 3rd try.
}

更多例子请参阅 XCTest 案例文档。

API 参考

Task.init(initClosure:)

initClosure中定义您的task

let task = Task<Float, NSString?, NSError> { progress, fulfill, reject, configure in

    player.doSomethingWithCompletion { (value: NSString?, error: NSError?) in
        if error == nil {
            fulfill(value)
        }
        else {
            reject(error)
        }
    }
}

为了通过 then()/success()/failure() 管道未来的 task.valuetask.errorInfo(一个包含 (error: Error?, isCancelled: Bool) 的元组),), 您必须在 initClosure 中调用 fulfill(value) 和/或 reject(error)

可选地,在调用 fulfill/reject 之前,您可以多次调用 progress(progressValue) 来传输 progressValueinitClosure 之外,通知给 task 本身。

为了将 pause/resume/cancel 功能添加到您的 task 中,请使用 configure 来包裹原始功能。

// NOTE: use weak to let task NOT CAPTURE player via configure
configure.pause = { [weak player] in
    player?.pause()
}
configure.resume = { [weak player] in
    player?.resume()
}
configure.cancel = { [weak player] in
    player?.cancel()
}

task.progress(_ progressClosure:) -> task

task.progress { (oldProgress: Progress?, newProgress: Progress) in
    println(newProgress)
    return
}.success { ... }

task.progress(progressClosure) 会将 progressClosure 添加为观察旧的/新的 progressValue,这些值是从之前的 initClosure 内部通知的。此方法将返回 相同任务,因此它对于与随后的 then/success/failure 连接非常有用。

task.then(_ thenClosure:) -> newTask

task.then(thenClosure) 将返回一个新的任务,其中当 task 要么是 fulfilled 要么是 rejected 时将调用 thenClosure

此情况类似于 JavaScript 的 promise.then(onFulfilled, onRejected)

thenClosure 可以是两种类型的闭包形式

  1. thenClosure: (Value?, ErrorInfo?) -> Value2(流:task => newTask

    // let task will be fulfilled with value "Hello"
    
    task.then { (value: String?, errorInfo: ErrorInfo?) -> String in
        // nil-check to find out whether task is fulfilled or rejected
        if errorInfo == nil {
            return "\(value!) World"
        }
        else {
            return "\(value!) Error"
        }
    }.success { (value: String) -> Void in
        println("\(value)")  // Hello World
        return"
    }
  2. thenClosure: (Value?, ErrorInfo?) -> Task(流:task => task2 => newTask

    // let task will be fulfilled with value "Hello"
    
    task.then { (value: String?, errorInfo: ErrorInfo?) -> Task<Float, String, NSError> in
        if errorInfo == nil {
            // let task2 will be fulfilled with value "\(value!) Swift"
            let task2 = ...
            return task2
        }
        else {
            return someOtherTask
        }
    }.success { (value: String) -> Void in
        println("\(value)")  // Hello Swift
        return"
    }

task.success(_ successClosure:) -> newTask

类似于 then() 方法,task.success(successClosure) 将返回一个新任务,但这次,仅在任务 仅 fulfilled 时调用 successClosure

这种情况类似于 JavaScript 的 promise.then(onFulfilled)

// let task will be fulfilled with value "Hello"

task.success { (value: String) -> String in
  return "\(value) World"
}.success { (value: String) -> Void in
  println("\(value)")  // Hello World
  return"
}

task.failure(_ failureClosure:) -> newTask

success() 正好相反,task.failure(failureClosure) 将返回一个新任务,其中 failureClosure 将在任务 仅 rejected/cancelled 时调用。

这种情况类似于 JavaScript 的 promise.then(undefined, onRejected)promise.catch(onRejected)

// let task will be rejected with error "Oh My God"

task.success { (value: String) -> Void in
    println("\(value)") // never reaches here
    return
}.failure { (error: NSError?, isCancelled: Bool) -> Void in
    println("\(error!)")  // Oh My God
    return
}

task.try(_ tryCount:) -> newTask

请参阅 可重试部分

Task.all(_ tasks:) -> newTask

Task.all(tasks) 是一个新任务,该任务同时执行所有 tasks 并将

  • 所有任务都 fulfilled 时被 fulfilled
  • 任何任务被 rejected 时被 rejected

Task.any(_ tasks:) -> newTask

Task.any(tasks)Task.all(tasks) 的对立面,它将在

  • 任何任务被 fulfilled 时被 fulfilled
  • 所有任务被 rejected 时被 rejected

Task.some(_ tasks:) -> newTask

Task.some(tasks) 是一个执行所有 tasks 而不内部 rejected 的新任务,并以给定的 tasks 的 fulfilled 值来 fulfiling。请注意,即使在所有 tasks 都被 rejected 的情况下,这个新任务也需要以空的值数组被 fulfiling。

相关文章

许可

MIT