所以,在发布后不久,我就想出了一个解决办法。我的问题有两个方面:
-
关闭我的频道以便它知道何时停止收听
-
使用不一致的方法将数据从goroutine获取到调用函数。对于使用chan的错误,但对于自定义结构,我只是设置它。我将chan泛化为接口{},然后在处理时对其进行类型切换,以确定它是什么类型的结构。
^^^解决这些问题使我的代码能够工作,但这里是我的代码最终的结果。。
func createWorkoutPlanForUserPreconditionCheck(planID, userID, transactionID *string) (*sharedstructs.Plan, *sharedstructs.User, *sharedstructs.Profile, error) {
if planID == nil || userID == nil || transactionID == nil {
return nil, nil, nil, sharedstructs.InvalidData{Msg: "Cannot pass in Nil Parameters"}
}
outputChannel := make(chan interface{}, 3)
var wg sync.WaitGroup
wg.Add(3)
//Get the Plan from the Plan ID
go func() {
defer wg.Done()
returnedPlan, readError := readPlan(*planID)
if readError != nil || returnedPlan == nil {
outputChannel <- sharedstructs.InvalidData{Msg: "Could Not Retreive the User with ID: " + *userID}
} else {
outputChannel <- *returnedPlan
}
}()
//Get the User
go func() {
defer wg.Done()
returnedUser, getUserError := userdomain.GetUserByID(*userID, *transactionID)
if getUserError != nil || &returnedUser == nil {
outputChannel <- sharedstructs.InvalidData{Msg: "Could Not Retreive the User with ID: " + *userID}
} else {
outputChannel <- returnedUser
}
}()
//Get the Profile
go func() {
defer wg.Done()
readProfile, getProfileError := profiledomain.GetProfile(*userID, *transactionID)
if getProfileError != nil || readProfile == nil {
outputChannel <- sharedstructs.InvalidData{Msg: "Could Not Retreive the User with ID: " + *userID}
} else {
outputChannel <- *readProfile
}
}()
wg.Wait()
close(outputChannel)
plan := sharedstructs.Plan{}
user := sharedstructs.User{}
profile := sharedstructs.Profile{}
for result := range outputChannel {
switch result.(type) {
case sharedstructs.InvalidData:
return nil, nil, nil, result.(sharedstructs.InvalidData)
case sharedstructs.Plan:
plan = result.(sharedstructs.Plan)
case sharedstructs.User:
user = result.(sharedstructs.User)
case sharedstructs.Profile:
profile = result.(sharedstructs.Profile)
}
}
return &plan, &user, &profile, nil
}