使用 BubbleWrap 的 RubyMotion 异步编程

标签 ruby asynchronous rubymotion single-responsibility-principle

当使用大量异步代码时,我对如何编写像样的代码感到困惑。

在下面的代码片段中,我登录以获取身份验证 cookie 并将该 cookie 用于下一个请求以获取项目名称列表(作为示例):

def self.populateProjectsTable(projects_controller)
  payload = {email: "email", password: "pass"}
  HTTP.post("http://example.com/login", {payload: payload}) do |response|
    authCookie = response.headers['Set-Cookie']
    HTTP.get("http://example.com/projects.json", {cookie: authCookie}) do |response|
      projects = JSON.parse(response.body.to_str)
      projects_controller.projects = projects
      projects_controller.reloadData
    end
  end
end

虽然这会起作用,但代码感觉很脏。没有真正遵循单一职责原则。我想用几种方法提取它:

def self.populateProjectsTable(projects_controller)
  @taskList = TaskList.new
  @taskList.doLogin
  projects = @taskList.getProjects
  projects_controller.projects = projects
  projects_controller.reloadData
end

def doLogin
  payload = {email: "email", password: "pass"}
  HTTP.post("http://example.com/login", {payload: payload}) do |response|
    @authCookie = response.headers['Set-Cookie']
  end
end

def getProjects
  HTTP.get("http://example.com/projects.json", {cookie: @authCookie}) do |response|
    projects = JSON.parse(response.body.to_str)
  end
end

这显然行不通。 getProjects 方法在 doLogin 完成之前调用,项目仅在 block 范围内已知,不会将数据返回给 populateProjectsTable 方法。

如何在没有第一个示例中所示的嵌套的情况下编写此类应用程序?

最佳答案

您不会完全摆脱嵌套。接受艾伦的回答并稍微修改一下,这就是我想出的。它涉及通过几种方法传递一个 block 。

def self.populateProjectsTable(projects_controller)
  @taskList = TaskList.new
  @taskList.loginAndGetProjects do |projects|
    projects_controller.projects = projects
    projects_controller.reloadData
  end
end

def loginAndGetProjects(&block)
  payload = {email: "email", password: "pass"}
  HTTP.post("http://example.com/login", {payload: payload}) do |response|
    @authCookie = response.headers['Set-Cookie']
    getProjects(&block)
  end
end

def getProjects(&block)
  HTTP.get("http://example.com/projects.json", {cookie: @authCookie}) do |response|
    projects = JSON.parse(response.body.to_str)
    block.call(projects)
  end
end

关于使用 BubbleWrap 的 RubyMotion 异步编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13167304/

相关文章:

ruby-on-rails - 如何在 Ruby Net::FTP 中使用代理服务器?

ruby-on-rails - Ruby 如何知道在哪里可以找到所需的文件?

ios - 无法在 Swift 中使用范围方法之外的变量(dataTaskWithRequest)

c# - 从非异步运行 async() 无需等待

java - Servlet对Requests的异步处理

objective-c - 从 MacRuby 中的自定义初始化程序调用不同的父类(super class)初始化方法

ruby - 在项目之间共享类的最佳实践

ruby - 创建 Ruby gem 时如何测试?

ruby-on-rails - 在 rails 中相交列表的最快方法?

ruby - MacRuby 指向 typedef 结构的指针