2

我正在编写一个使用解析服务器(由 heroku 托管)数据库的应用程序。我有几个从数据库中提取信息的函数,但它们本质上都是异步的(因为 parse 的.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(在查询中)是异步的。在下一个可以触发之前,特别需要拉出对象,而不仅仅是查询运行。

4

1 回答 1

1

你想创造你的承诺吗?

您需要编写一个返回 a 的函数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 有更好的类型推断,但是,当使用 PromiseKit 时,我建议总是在then闭包中编写一个类型,以避免错误。

于 2017-03-19T00:50:22.677 回答