完成处理程序在运行另一个任务之前完成任务

Posted

技术标签:

【中文标题】完成处理程序在运行另一个任务之前完成任务【英文标题】:completion handler to finish tasks before running another 【发布时间】:2017-01-05 02:12:05 【问题描述】:

我真的把自己绑在一个结里,对如何按照我希望它们发生的顺序执行任务感到非常困惑。

我具有从服务器数据构建数组并返回数组结果的功能。 - 这工作正常并返回结果。

在这件事完成后(两次),我想运行另一个函数。出于某种原因,目前我正试图将这些函数嵌入另一个带有完成块的函数中,一旦这两个函数完成并返回数据,该块将返回 true,但我尝试这样做的方式是在函数完成之前返回结果.

func getCollectionArrays(_ block: ((Bool) -> Void)? = nil) 

    var resultPack: Bool!
    var resultPart: Bool!

        BuildArray.buildArrayFromQuery(queryForCollection: "Pack", sender: self, completeBlock:  (result) in

            if result != nil 

                resultPack = true
            

        )

                BuildArray.buildArrayFromQuery(queryForCollection: "Part", sender: self, completeBlock:  (result) in

                    if result != nil 

                        resultPart = true
                    

                )

    // this is returning nil because there isn't enough time for "BuildArray.buildArrayFromQuery" to run
    if resultPack == true && resultPart == true 

        block!(true)

    


【问题讨论】:

仅供参考 - 如果 blocknilblock!(true) 将崩溃。不要强制打开一个可选的。 【参考方案1】:

将下一步移到前面的闭包中。继续筑巢。像这样:

func getCollectionArrays(_ block: ((Bool) -> Void)? = nil) 
    var resultPack: Bool!
    var resultPart: Bool!
    BuildArray.buildArrayFromQuery(queryForCollection: "Pack", sender: self, completeBlock:  (result) in
        if result != nil 
            resultPack = true
        
        // next step, nested in this closure
        BuildArray.buildArrayFromQuery(queryForCollection: "Part", sender: self, completeBlock:  (result) in
            if result != nil 
                resultPart = true
            
            // next step, nested in _this_ closure
            if resultPack == true && resultPart == true 
                block!(true)
            
        )
    )

【讨论】:

出于某种原因,我认为重复嵌套是个坏主意 绝不是。 GCD 嵌套通常会深入很多层(切换到后台线程,然后切换到主线程......)。基本上,当事情是异步时,这种嵌套是让事情按照你想要的顺序发生的唯一方法。这就是异步的意思 不要使用block!。如果blocknil(这是默认值),您的代码将会崩溃。 是的,使用block?() @Pippo - 关于嵌套,是的,如果你做太多次它会变得笨拙(例如,想象你有十几个级别的嵌套调用......那会很疯狂)。但是您只需将它们分成不同的方法并保持干净。或者您可以使用承诺/期货(如 PromiseKit 或 RXPromise)。或者您可以使用具有依赖关系的操作。但是只有两层嵌套,我不会担心。

以上是关于完成处理程序在运行另一个任务之前完成任务的主要内容,如果未能解决你的问题,请参考以下文章

c# TaskFactory ContinueWhenAll 在所有任务完成之前意外运行

运行多个异步任务并等待它们全部完成

如何等待 ExecutorService 中的一个正在运行的线程完成分配另一个任务

调用 vbs 的批处理文件不会从任务调度程序运行

长时间运行的后台任务完成后应用程序未挂起

如何从事件处理程序返回任务?