function refresh1(){
if(NOT ZOOMED IN ON LINE){
if(document.getElementById("Line")){
$("#Line").data("kendoChart").dataSource.read();
$("#Line").data("kendoChart").refresh();
}
}
}
当两个功能完成后,如何进行通信?我希望能够编写我的加载函数的completionHandler,以便在完成BOTH asyncFunc1和asyncFunc2时执行,然后返回someVar1和someVar2。
答案 0 :(得分:3)
您可以使用计数器来了解两种方法何时完成执行。拥有一个计数器更具可扩展性,因为它允许几乎任意数量的异步方法:
func load(completionHandler:(someVar1 : SomeType, someVar2 : SomeType) -> Void){
var callbacksLeft = 2
let completionCallback = {
print("All calls completed, let's do some work")
}
func checkCompleted() {
callbacksLeft -= 1
if callbacksLeft == 0 {
completionCallback()
}
}
asyncFunc1() { someVar1 in
checkCompleted()
}
asyncFunc2() { someVar2 in
checkCompleted()
}
}
或者,如果可以以相同的方式调用函数,例如两者都没有params,或者有相同的参数列表,你可以通过使用一个数组来缩短代码(这也不像在第一个实现中那样,如果你添加一个新函数,你必须在两个地方更新代码) - 更新callbacksLeft
值,并添加实际的函数调用):
func load(completionHandler:(someVar1 : SomeType, someVar2 : SomeType) -> Void){
let funcsToCall = [asyncFunc1, asyncFunc2]
var callbacksLeft = funcsToCall.count
let completionCallback = {
print("All calls completed, let's do some work")
}
for funcToCall in funcsToCall {
funcToCall {
callbacksLeft -= 1
if callbacksLeft == 0 {
completionCallback()
}
}
}
}
即使函数没有以相同的方式调用,也可以将它们包装在闭包中:
let funcWrapper1 = { (callback: () -> Void)
return asyncFunc1(argumentsForFuc1, callback)
}
let funcWrapper2 = { (callback: () -> Void)
return asyncFunc2(argumentsForFunc2, callback)
}
let funcsToCall = [funcWrapper1, funcWrapper2]
答案 1 :(得分:0)
我不确定此方法的效率如何,但您可以声明两个全局变量初始化为nil
,并且当每个方法完成执行时,您可以将其各自的全局变量设置为{{1} }或someVar1
值,并调用第三个方法,只有当这两个全局变量都不是someVar2
时才会执行。
nil
答案 2 :(得分:0)
我建议你根本不要使用全局变量。在第一个异步函数中使用完成处理程序来调用第二个异步函数。请检查我的示例代码。
enum ErrorMessage:ErrorType {
case asyncFunc1Error
case asyncFunc2Error
}
func asyncFunc1(completion:(result:SomeType?,error:ErrorType?) ->Void) {
print("Do Something Func 1")
var result:SomeType? //fill it
//do some checks
if true {
completion(result: result,error: nil)
} else {
completion(result: nil,error: ErrorMessage.asyncFunc1Error)
}
}
func asyncFunc2(completion:(result:SomeType?,error:ErrorType?) ->Void) {
print("Do Something Func 2")
var result:SomeType? //fill it
//do some checks
if true {
completion(result: result,error: nil)
} else {
completion(result: nil,error: ErrorMessage.asyncFunc2Error)
}
}
func load(completionHandler:(someVar1 : SomeType?, someVar2 : SomeType?)-> Void){
asyncFunc1 { (result, error) -> Void in
if let realResult1 = result {
//we have result
print("Result1",realResult1)
//call second async
asyncFunc2({ (result, error) -> Void in
if let realResult2 = result {
print("Result2",realResult2)
// if we reach here it means async1 and async2 were successful
completionHandler(someVar1: realResult1, someVar2: realResult2)
} else {
//async2 failed
completionHandler(someVar1: realResult1, someVar2: nil)
}
})
} else {
//asyncfunc1 failed
//you can also send some error
completionHandler(someVar1: nil, someVar2: nil)
}
}
}