完成处理程序在运行另一个任务之前完成任务
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)
【问题讨论】:
仅供参考 - 如果block
是 nil
,block!(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!
。如果block
是nil
(这是默认值),您的代码将会崩溃。
是的,使用block?()
。
@Pippo - 关于嵌套,是的,如果你做太多次它会变得笨拙(例如,想象你有十几个级别的嵌套调用......那会很疯狂)。但是您只需将它们分成不同的方法并保持干净。或者您可以使用承诺/期货(如 PromiseKit 或 RXPromise)。或者您可以使用具有依赖关系的操作。但是只有两层嵌套,我不会担心。以上是关于完成处理程序在运行另一个任务之前完成任务的主要内容,如果未能解决你的问题,请参考以下文章
c# TaskFactory ContinueWhenAll 在所有任务完成之前意外运行