Ax 0.1.3

Ax 0.1.3

测试已经测试
语言语言 SwiftSwift
许可 MIT
发布最后发布2017年1月
SPM支持 SPM

Wilson Balderrama 维护。



Ax 0.1.3

  • 作者
  • Wilson Balderrama

Ax

Ax 是一个用于以有组织的方式控制异步执行流程的 Swift 库。受到了 async 库 的启发。

概述

需求

  • Xcode 8.0+
  • Swift 3.0+
  • iOS 9.0+

用途是什么?

问题

例如,当您的异步调用相互依赖时,那么一个简单的解决方案就是在下面的例子中这样嵌套调用

runAsync(afterSeconds: 2, completion: {
  let dataFromTask1 = 1

  self.runAsync(afterSeconds: 2, completion: {
    let dataFromTask2 = 2

    self.runAsync(afterSeconds: 2, completion: {
      let dataFromTask3 = 3

      self.runAsync(afterSeconds: 2, completion: {
        let dataFromTask4 = 4

        print(dataFromTask1) // 1
        print(dataFromTask2) // 2
        print(dataFromTask3) // 3
        print(dataFromTask4) // 4
      })
    })
  })
})

嵌套异步调用是编程中的常见问题,社区将其命名为:回调地狱“地狱之塔”

我们应该避免这种代码,因为它可能导致一些真正混乱、难以阅读的代码,这是不良的编程习惯。

解决方案

这时就轮到 Ax 出场,它可以帮助您以线性方式调用异步调用,给人一种运行同步调用的印象

import Ax

var dataFromTask1 = 0
var dataFromTask2 = 0
var dataFromTask3 = 0
var dataFromTask4 = 0

Ax.serial(
  tasks: [
    { done in
      self.runAsync(afterSeconds: 2) {
        dataFromTask1 = 1
        done(nil)
      }
    },
    { done in
      self.runAsync(afterSeconds: 2) {
        dataFromTask2 = 2
        done(nil)
      }
    },
    { done in
      self.runAsync(afterSeconds: 2) {
        dataFromTask3 = 3
        done(nil)
      }
    },
    { done in
      self.runAsync(afterSeconds: 2) {
        dataFromTask4 = 4
        done(nil)
      }
    }
  ],
  result: { error in // feedback closure
    print(dataFromTask1)  // outputs 1
    print(dataFromTask2)  // outputs 2
    print(dataFromTask3)  // outputs 3
    print(dataFromTask4)  // outputs 4
  }
)

要提及的重要方面

  • 变量 done 是一个接收 NSError? 值的闭包,当 done 被调用并传入 nil 时,意味着任务运行成功;另一方面,如果 done 被调用并传入一个 NSError 值,则忽略所有后续任务,并立即用传递给 done 的错误值执行 result 闭包。
  • tasksresult 中的 闭包DispatchQoS.QoSClass.background 模式运行,如果您需要,例如,在主线程中调用结果,则由您自己决定。

支持函数

最初支持的函数包括

  • 串行
  • 并行

串行

该函数帮助你以顺序方式执行异步调用,按照有序的方式进行,首先运行第一个调用,完成后,然后运行下一个调用,以此类推。

示例

import Ax

var authorId = ""
var authorBooks = [Book]()

Ax.serial(
  tasks: [
    { done in
      self.getAuthorBy(name: "J. K. Rowling") { error, author in
        guard let author = author else {
          done(NSError(domain: "AppDomain", code: 434, userInfo: [NSLocalizedDescriptionKey: "didn't get author"]))
          return
        }

        authorId = author.id
        done(error)
      }
    },
    { done in
      self.getBooksBy(authorId: authorId, completion: { (error, books: [Book]) in
        authorBooks = books
        done(error)
      })
    }
  ],
  result: { error in
    if let error = error {
      print(error)
      return
    }

    print(authorBooks) // [Book(name: "Harry Potter and the Philosopher\'s Stone"), Book(name: "Harry Potter and the Chamber of Secrets")]
  }
)

并行

帮助你以并行方式执行异步调用,当你需要执行许多固定调用时,该功能将帮助你,但这些调用是否同时运行并不重要。

示例

import Ax

let userId = "1"
let profileImageURL = "https://unsplash.it/100"

var userFound: User?
var userImage: UIImage?

Ax.parallel(
  tasks: [
    { done in

      self.getUserBy(id: userId) { error, user in
        guard let user = user else {
          done(NSError(domain: "AppDomain", code: 434, userInfo: [NSLocalizedDescriptionKey: "No user found."]))
          return
        }

        userFound = user
        done(error)
      }
    },
    { done in

      self.getProfileImageBy(url: profileImageURL) { error, image in
        guard let image = image else {
          done(NSError(domain: "AppDomain", code: 435, userInfo: [NSLocalizedDescriptionKey: "Image not found."]))
          return
        }

        userImage = image
        done(error)
      }
    }
  ],
  result: { error in
    if let error = error {
      print(error)
      return
    }

    print(userFound!) // User(name: "Walter While")
    print(userImage!) // <UIImage: 0x618000095a90>, {100, 100}
  }
)

安装

Ax通过CocoaPods提供。要安装它,只需将以下行添加到您的Podfile中

pod "Ax"

用法

安装后,只需将其导入到您正在工作的文件中

import Ax

作者

Wilson Balderrama,[email protected]

许可

Ax可供MIT许可下使用。有关更多信息,请参阅LICENSE文件。