脚本宝典收集整理的这篇文章主要介绍了Swift之深入解析如何实现Promise,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
func load(_ callback: (Value) -> Void) {
loadService.load { result in
let saveableITem = result.transFromToSaveableitem
saveQueue.async {
saveService.save(saveableItem) { saved in
let displayableItem = saved.tranfromToDisplayableItem
mainQueue.async {
callback(displayableItem)
}
}
}
}
}
APIClient.fetchcurrentUser(success: { currentUser in
APIClient.fetchFollowers(user: currentUser, success: { followers in
// 得到一个 followers 数组
}, failure: { error in
// 错误处理
})
}, failure: { error in
// 错误处理
})
APIClient.fetchCurrentUser().then({ currentUser in
return APIClient.fetchFollowers(user: currentUser)
}).then({ followers in
// you now have an array of followers
)}.onFailure({ error in
// hooray, a single failure block!
})
VAR PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function Promise() {
// 保存 PENDING, FULFILLED 或者 REJECTED 的状态
var state = PENDING;
// 当出现 FULFILLED 或 REJECTED 状态时保存值或者错误
var value = null;
// 保存被 .then 或者 .done 函数触发的成功 & 失败的处理操作
var handlers = [];
}
enum State<Value> {
case pending
case fulfilled(value: Value)
case rejected(error: ErrorType)
}
final class Promise<Value> {
private var state: State<Value>
private var callbacks: [Callback<Value>] = []
}
var promise = new Promise(function(resolve, reject) {
someAsyncRequest(function(error, result) {
if (error) {
reject(error);
}
resolve(result);
});
});
let promise = Promise(value: "initialValue") // a fulfilled Promise<String>
let promise = Promise<String, APIError>(value: "initialValue")
test(named: "0. Executor function is called immediately") { assert, done in
var string: String = ""
_ = Promise { string = "foo" }
assert(string == "foo")
done()
}
error: Promise.playground:41:9: error: use of unresolved identifier 'Promise'
_ = Promise { string = "foo" }
^~~~~~~
class Promise {
}
error: Promise.playground:44:17: error: argument passed to call that takes no arguments
_ = Promise { string = "foo" }
^~~~~~~~~~~~~~~~~~
class Promise {
init(executor: () -> Void) {
executor()
}
}
Test 0. Executor function is called immediately passed
test(named: "1.1 Resolution handler is called when promise is resolved sync") { assert, done in
let string: String = "foo"
let promise = Promise<String> { resolve in
resolve(string)
}
promise.then { (value: String) in
assert(string == value)
done()
}
}
test(named: "1.2 Resolution handler is called when promise is resolved async") { assert, done in
let string: String = "foo"
let promise = Promise<String> { resolve in
after(0.1) {
resolve(string)
}
}
promise.then { (value: String) in
assert(string == value)
done()
}
}
error: Promise.playground:54:19: error: cannot specialize non-generic type 'Promise'
let promise = Promise<String> { resolve in
^ ~~~~~~~~
class Promise<Value> {
init(executor: () -> Void) {
executor()
}
}
error: Promise.playground:54:37: error: contextual closure type '() -> Void' expects 0 arguments, but 1 was used in closure body
let promise = Promise<String> { resolve in
^
class Promise<Value> {
init(executor: (_ resolve: (Value) -> Void) -> Void) {
executor()
}
}
class Promise<Value> {
init(executor: (_ resolve: @escaping (Value) -> Void) -> Void) {
executor(resolve)
}
private func resolve(_ value: Value) -> Void {
// To implement
// This will be called by the outside world when a value is determined
}
}
error: Promise.playground:61:5: error: value of type 'Promise<String>' has no member 'then'
promise.then { (value: String) in
^~~~~~~ ~~~~
class Promise<Value> {
init(executor: (_ resolve: @escaping (Value) -> Void) -> Void) {
executor(resolve)
}
func then(onResolved: @escaping (Value) -> Void) {
// To implement
}
private func resolve(_ value: Value) -> Void {
// To implement
}
}
enum State<T> {
case pending
case resolved(T)
}
class Promise<Value> {
enum State<T> {
case pending
case resolved(T)
}
private var state: State<Value> = .pending
init(executor: (_ resolve: @escaping (Value) -> Void) -> Void) {
executor(resolve)
}
func then(onResolved: @escaping (Value) -> Void) {
// To implement
}
private func resolve(_ value: Value) -> Void {
// To implement
}
private func updateState(to newState: State<Value>) {
Guard case .pending = state else { return }
state = newState
}
}
private func resolve(_ value: Value) -> Void {
updateState(to: .resolved(value))
}
class Promise<Value> {
enum State<T> {
case pending
case resolved(T)
}
private var state: State<Value> = .pending
// we Store the callback as an instance variable
private var callback: ((Value) -> Void)?
init(executor: (_ resolve: @escaping (Value) -> Void) -> Void) {
executor(resolve)
}
func then(onResolved: @escaping (Value) -> Void) {
// store the callback in all cases
callback = onResolved
// and trigger it if needed
triggerCallbackIfResolved()
}
private func resolve(_ value: Value) -> Void {
updateState(to: .resolved(value))
}
private func updateState(to newState: State<Value>) {
guard case .pending = state else { return }
state = newState
triggerCallbackIfResolved()
}
private func triggerCallbackIfResolved() {
// the callback can be triggered only if we have a value,
// meaning the promise is resolved
guard case let .resolved(value) = state else { return }
callback?(value)
callback = nil
}
}
Test 1.1 Resolution handler is called when promise is resolved sync passed (1 assertions)
Test 1.2 Resolution handler is called when promise is resolved async passed (1 assertions)
test(named: "2.1 Promise supports many resolution handlers sync") { assert, done in
let string: String = "foo"
let promise = Promise<String> { resolve in
resolve(string)
}
promise.then { value in
assert(string == value)
}
promise.then { value in
assert(string == value)
done()
}
}
test(named: "2.2 Promise supports many resolution handlers async") { assert, done in
let string: String = "foo"
let promise = Promise<String> { resolve in
after(0.1) {
resolve(string)
}
}
promise.then { value in
assert(string == value)
}
promise.then { value in
assert(string == value)
done()
}
}
Test 2.1 Promise supports many resolution handlers sync passed (2 assertions)
Test 2.2 Promise supports many resolution handlers async passed (1 assertions)
class Promise<Value> {
enum State<T> {
case pending
case resolved(T)
}
private var state: State<Value> = .pending
// We now store an array instead of a single function
private var callbacks: [(Value) -> Void] = []
init(executor: (_ resolve: @escaping (Value) -> Void) -> Void) {
executor(resolve)
}
func then(onResolved: @escaping (Value) -> Void) {
callbacks.append(onResolved)
triggerCallbacksIfResolved()
}
private func resolve(_ value: Value) -> Void {
updateState(to: .resolved(value))
}
private func updateState(to newState: State<Value>) {
guard case .pending = state else { return }
state = newState
triggerCallbacksIfResolved()
}
private func triggerCallbacksIfResolved() {
guard case let .resolved(value) = state else { return }
// We trigger all the callbacks
callbacks.foreach { callback in callback(value) }
callbacks.removeAll()
}
}
Test 2.1 Promise supports many resolution handlers sync passed (2 assertions)
Test 2.2 Promise supports many resolution handlers async passed (2 assertions)
test(named: "3. Resolution handlers can be chained") { assert, done in
let string: String = "foo"
let promise = Promise<String> { resolve in
after(0.1) {
resolve(string)
}
}
promise
.then { value in
return Promise<String> { resolve in
after(0.1) {
resolve(value + value)
}
}
}
.then { value in // the "observe" previously defined
assert(string + string == value)
done()
}
}
error: Promise.playground:143:10: error: value of tuple type '()' has no member 'then'
.then { value in
^
func then<NewValue>(onResolved: @escaping (Value) -> Promise<NewValue>) -> Promise<NewValue> {
// to implement
}
func then<NewValue>(onResolved: @escaping (Value) -> Promise<NewValue>) -> Promise<NewValue> {
then { value in // the "observe" one
let promise = onResolved(value) // `promise` is a Promise<NewValue>
// problem: how do we return `promise` to the outside ??
}
return // ??!!
}
func then<NewValue>(onResolved: @escaping (Value) -> Promise<NewValue>) -> Promise<NewValue> {
// We have to return a promise, so let's return a new one
return Promise<NewValue> { resolve in
// this is called immediately as seen in test 0.
then { value in // the "observe" one
let promise = onResolved(value) // `promise` is a Promise<NewValue>
// `promise` has the same type of the Promise wrapper
// we can make the wrapper resolves when the `promise` resolves
// and gets a value
promise.then { value in resolve(value) }
}
}
}
// observe
func then(onResolved: @escaping (Value) -> Void) {
callbacks.append(onResolved)
triggerCallbacksIfResolved()
}
// flatMap
func then<NewValue>(onResolved: @escaping (Value) -> Promise<NewValue>) -> Promise<NewValue> {
return Promise<NewValue> { resolve in
then { value in
onResolved(value).then(onResolved: resolve)
}
}
}
Test 3. Resolution handlers can be chained passed (1 assertions)
test(named: "4. Chaining works with non promise return values") { assert, done in
let string: String = "foo"
let promise = Promise<String> { resolve in
after(0.1) {
resolve(string)
}
}
promise
.then { value -> String in
return value + value
}
.then { value in // the "observe" then
assert(string + string == value)
done()
}
}
error: Promise.playground:174:26: error: declared closure result 'String' is incompatible with contextual type 'Void'
.then { value -> String in
^~~~~~
Void
// map
func then<NewValue>(onResolved: @escaping (Value) -> NewValue) -> Promise<NewValue> {
// to implement
}
// map
func then<NewValue>(onResolved: @escaping (Value) -> NewValue) -> Promise<NewValue> {
return then { value in // the "flatMap" defined before
// must return a Promise<NewValue> here
// this promise directly resolves with the mapped value
return Promise<NewValue> { resolve in
let newValue = onResolved(value)
resolve(newValue)
}
}
}
Test 4. Chaining works with non promise return values passed (1 assertions)
// observe
func then(onResolved: @escaping (Value) -> Void) {
callbacks.append(onResolved)
triggerCallbacksIfResolved()
}
// flatMap
func then<NewValue>(onResolved: @escaping (Value) -> Promise<NewValue>) -> Promise<NewValue> {
return Promise<NewValue> { resolve in
then { value in
onResolved(value).then(onResolved: resolve)
}
}
}
// map
func then<NewValue>(onResolved: @escaping (Value) -> NewValue) -> Promise<NewValue> {
return then { value in
return Promise<NewValue> { resolve in
resolve(onResolved(value))
}
}
}
struct User {
let id: Int
let name: String
}
func fetchIds() -> Promise<[Int]> {
...
}
func fetchUser(id: Int) -> Promise<User> {
...
}
fetchIds()
.then { ids in // flatMap
return fetchUser(id: ids[0])
}
.then { user in // map
return user.name
}
.then { name in // observe
print(name)
}
以上是脚本宝典为你收集整理的Swift之深入解析如何实现Promise全部内容,希望文章能够帮你解决Swift之深入解析如何实现Promise所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。