【问题标题】:How to ensure a query happens before another query within the same function?如何确保查询发生在同一函数中的另一个查询之前?
【发布时间】:2017-02-25 15:15:29
【问题描述】:

我有一个函数,其中设置了多个查询。该功能很长,涉及很多,但效果很好,除了一个问题。有一个查询依赖于之前查询的某些信息,当之前的查询未完全完成并导致第二个查询解包 nil 值时,它偶尔会使应用程序崩溃。这是一般设置:

func QueryandAppend(completion: (() -> Void)?){
    let userLinkQuery = PFUser.query()//query1
    userLinkQuery?.findObjectsInBackground(block: { (objects, error) in
        if let users = objects{
            for object in users{
                if let user = object as? PFUser{
                    userLinkArray[user.objectId!] = user.username
                }
            }
        }
        })

        let appendingQuery = PFQuery(classname: "Stuff")//query2
            appendingQuery.findObjectsInBackground { (objects, error) in
            for object in objects{
               creatorArray.append(userLinkArray[object["User"] as! String]!)
            }
            ...
            completion!()

    }

完成处理程序用于确保在运行 viewDidLoad() 中的某些内容之前已完成整个函数(以及所有查询)。但是,我如何确保 函数 query1 在 query2 可以运行之前完成?

【问题讨论】:

  • 查询是如何执行的,您的目标是哪个数据库?并行运行的查询是数据库的一项功能,还是您使用 GCD?
  • @kennytm 我正在使用由 heroku 托管的解析服务器作为数据库。它们并行运行并不是一个特定的功能。这只是我拥有的一般设置。我想,由于 query1 是在 query2 之前编写的,所以它总是会首先运行......在编码方面有点新
  • 我假设您使用的是Parse SDK?
  • @kennytm 是的,这就是我正在使用的

标签: swift parse-platform


【解决方案1】:

使用网络和其他异步操作执行此操作的典型方法是将操作链接起来,甚至可能将各个网络操作分解为一个特定的例程。各个操作都有完成回调,因此只需从第一个例程的完成调用您的第二个例程。

func QueryandAppend(completion: ((Bool) -> Void)?) {
    PFUser.query().findObjectsInBackground { (objects, error) in
        guard error == nil, let users = objects else {
            completion?(false)
            return
        }

        for object in users {
            if let user = object as? PFUser,
                let objectId = user.objectId {
                userLinkArray[objectId] = user.username
            }
        }

        PFQuery(classname: "Stuff").findObjectsInBackground { (objects, error) in
            if error != nil {
                // Handle error case
                completion?(false)
                return
            }

            for object in objects {
                creatorArray.append(userLinkArray[object["User"] as! String]!)
            }

            completion?(true)
        }
    }
}

或者,对于更现代的风格方法,您可以查看一个好的 Promise 框架,例如 PromiseKit

【讨论】:

  • 您能解释一下if successful 的意思吗?实际的 query1 拉取一个对象并使用该对象的一个​​参数来追加一个数组。你能用我所拥有的代码的更多细节来解释你的答案吗?我不太了解一般意义上的回调(尽管查找了它们)我已经使用第一个查询的特定代码编辑了问题。
  • 两个查询**
猜你喜欢
  • 1970-01-01
  • 2019-06-29
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多