如何修复附加函数的异步性质?

How to fix the asynchronous nature of my appending function?

我设置了一个查询以从数据库(由 heroku 托管的 Parse-server)中提取数据并将其附加到数组;在此查询中是另一个查询,用于从不同的 class 中提取信息,但也用于附加另一个数组。我认为因为我使用 .findObjectsinBackground 它是异步发生的,这导致了一个问题。这是代码(通用):

    func getQueries(completion: (() -> Void)?){

        let searchQuery = PFQuery(className: "Etc")         
        searchQuery.findObjectsInBackground(block: { (objects, error) in

            if let objectss = objects{

                for object in objectss {
                    //append some arrays
                    let otherQuery = PFQuery(className: "OtherClass")
                    otherQuery.whereKey("user", equalTo: object["User"] as String)
                    otherQuery.findObjectsInBackground(block: {(objects, error) in
                        if let objectss = objects{
                            for object in objectss{
                                array.append(object["ProfPic"] as PFFile)
                                print("\(array) and its count is \(array.count)") //this returns a non 0 value
                            }
                        }
                        completion!()
                    })

            print("\(array) and its count is \(array.count)") //this returns 0
                }
            }
         })
    }

array 的计数一旦被附加到它自己的闭包中就返回为非 0,但在其闭包之外返回为 0。这是一个问题,因为数组用于迭代显示信息。无论如何要确保在完成 searchQuery 的整体关闭之前,otherQuery 的追加已经完成? (另外,它是异步发生导致问题的事实是一个猜测......我可能是错的)

在后一种情况下,您将在获取数据之前打印计数,例如在 findObjectsInBackground.

的完成块之外

您可以将整个事情包装在一个带有完成块的自己的方法中:

func fetchData(_ completion: () -> Void) {

    searchQuery.findObjectsInBackground(block: { (objects, error) in
        guard let objectss = objects else {
            completion() 
        }

        for object in objectss {
            let otherQuery = PFQuery(className: "OtherClass")
            otherQuery.whereKey("user", equalTo: object["User"] as String)
            otherQuery.findObjectsInBackground(block: {(objects, error) in

                guard let objectss = objects else {
                    completion()
                }

                for object in objectss{
                    array.append(object["ProfPic"] as PFFile)
                }

                print("In loop: \(array) and its count is \(array.count)")                
                completion()
            })
        }
    })
}

比这更重要的是:

fetchData() {
     print("After completing: \(array) and its count is \(array.count)")
    // do stuff with your fetched data and display it
    // "use in iterating through to display information" here
}

更新:

在您更新的问题中,您仅在成功案例中调用 completion!()。在任何情况下你都必须调用它:

...
if let objectss = objects 
    ...
    completion!()
} else {
    completion!()
} 
...