如何利用PromiseKit确保在继续之前检索到查询的对象?

时间:2017-03-14 15:32:35

标签: swift xcode parse-server promisekit

我正在编写一个使用解析服务器(由heroku托管)数据库的应用程序。我有几个从数据库中提取信息的函数,但它们本身都是异步的(因为解析的.findObjectinBackground工作方式。)这个问题与后面的数据库查询需要先前查询的信息有关。 。由于提取的信息是异步的,我决​​定实现PromiseKit以确保在运行第二个查询之前从第一个查询中findObjectinBackground找到了对象。 查询的一般形式如下:

let query = PFQuery(classname: "Hello")
query?.findObjectsInBackground(block: { (objects, error) in
       if let objectss = objects{
           for object in objectss{ //object needs to be pulled
               arrayOfInterest.append(object)
               //array must be appended before moving on to next query

            }
        }            
})

我只是不知道如何做到这一点。这是我想要实现它的方式:

import PromiseKit
override func viewDidLoad(){
    when(/*query object is retrieved/array is appended*/).then{
        //perform the next query
    }
}

我根本不确切知道要放在when().then{}中的内容。我尝试将查询放入他们自己的各个函数中并在这两个函数中调用它们(当时和然后)函数,但我基本上被告知我不能,因为它们返回void。此外,我不能简单地确保when()中的第一个查询运行,因为query.findObjectinBackground(在查询中)是异步的问题。该对象特别需要 pull ,而不仅仅是查询运行,然后才能触发。

1 个答案:

答案 0 :(得分:1)

Do you want create your promise?

您需要编写一个返回Promise<Any>的函数。在您的情况下,需要将整个代码封装在Promise { fulfill, reject in HERE}内。例如:

func foo(className: String) -> Promise<[TypeOfArrayOfInterest]> {
    return Promise { fulfill, reject in

        let query = PFQuery(classname: className)
        query?.findObjectsInBackground(block: { (objects, error) in
            if let error = error {
                reject(error) // call reject when some error happened
                return
            }

            if let objectss = objects {
                for object in objectss{
                    arrayOfInterest.append(object)
                }

                fulfill(arrayOfInterest) // call fulfill with some value
            }
        })

    }
}

然后,您在firstly

中调用此函数
firstly {
    foo(className: "Hello")
}.then { myArrayOfInterest -> Void in
    // do thing with myArrayOfInterest
}.catch { error in
    // some error happened, and the reject was called!
}

另外,我在博客中写了一篇关于PromiseKit和架构的文章。它可能会有所帮助:http://macalogs.com.br/ios/rails/ifce/2017/01/01/experiencias-eventbee.html

修改

更完整的例子:

func foo() -> Promise<Int> {
    ...
}

func bar(someText: String) -> Promise<String> {
    ...
}

func baz() -> Promise<Void> {
    ...
}

func runPromises() {
    firstly {
        foo()
    }.then { value -> Promise<Any> in
        if value == 0 {
            return bar(someText: "no")
        } else {
            return bar(someText: "yes")
        }
    }.then { _ /* I don't want a String! */ -> Promise<Void> in
        baz()
    }.catch { error in
       // some error happened, and the reject was called!
    }
}

或者,如果您不想要catch

_ = firstly {
    foo()
}.then { _ in
    // do some thing
}

Swift有一个greate类型推断,但是,当使用PromiseKit时,我建议总是在then闭包中写一个类型,以避免错误。