如何利用 PromiseKit 确保在继续之前检索到查询的对象?
How to utilize PromiseKit to ensure a queried object has been retrieved before proceeding?
我正在编写一个使用解析服务器(由 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{}
中放什么。我尝试将查询放入它们自己的单独函数中,并在这两个(何时和然后)函数中调用它们,但我基本上被告知我不能,因为它们 return 无效。此外,我不能简单地确保第一个查询是 when()
中的 运行,因为 query.findObjectinBackground
(在查询中)是异步的是问题所在。该对象特别需要 拉取 ,而不仅仅是查询 运行,然后才能触发下一个对象。
Do you want create your promise?
您需要编写一个 return 和 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!
}
此外,我在我的博客中写了一篇 post,其中包括 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
闭包中写一个类型,以避免错误。
我正在编写一个使用解析服务器(由 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{}
中放什么。我尝试将查询放入它们自己的单独函数中,并在这两个(何时和然后)函数中调用它们,但我基本上被告知我不能,因为它们 return 无效。此外,我不能简单地确保第一个查询是 when()
中的 运行,因为 query.findObjectinBackground
(在查询中)是异步的是问题所在。该对象特别需要 拉取 ,而不仅仅是查询 运行,然后才能触发下一个对象。
Do you want create your promise?
您需要编写一个 return 和 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!
}
此外,我在我的博客中写了一篇 post,其中包括 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
闭包中写一个类型,以避免错误。