A "callback" is a callable(always is a function) that will be "called back".
when using a "callback", we pass a "callback" as a arguement to an non-blocking function.
callback的职责
callback function的职责,仅仅是通知,还是完成某些逻辑?
看具体情况
- 仅通知。如果非阻塞函数本身可以将任务的result存储下来,那么callback function可以仅仅承担通知【任务完成】的职责。原来的调用方收到任务完成后,再自行获取result执行自己的业务逻辑。这种情况下,callback function是不需要参数的
// You can edit this code!
// Click here and start typing.
// https://go.dev/play/p/Nkv8Rjl1nuK
package main
import (
"fmt"
"time"
)
var c = make(chan string)
func Work(taskName string, callback func()) {
// do something which kills time. like sleep...
time.Sleep(5 * time.Second)
callback() // callback with no arguement
}
func NoticeIfTaskFinished() {
c <- "finished"
}
func main() {
targetTask := "task"
go Work(targetTask, NoticeIfTaskFinished)
fmt.Println(targetTask, <-c)
}
- 仅回传最终结果。如果非阻塞函数本身不存储任务的result,那么我们可以利用callback function回传这个result。这时,callback function需要一个参数,用于接收任务的result。同时,这种情况是最常见的
// You can edit this code!
// Click here and start typing.
// https://go.dev/play/p/3DeEgcFk8-1
package main
import (
"fmt"
"math/rand"
"time"
)
var c = make(chan int)
func Work(taskName string, callback func(number int)) {
// do something which kills time. like sleep...
time.Sleep(5 * time.Second)
rand.Seed(time.Now().UnixNano())
randomNumber := rand.Intn(100)
callback(randomNumber) // callback to send the resulted randomNumber
}
func NoticeIfTaskFinished(number int) {
c <- number
}
func main() {
targetTask := "task"
go Work(targetTask, NoticeIfTaskFinished)
fmt.Println(targetTask, <-c, "finished")
}
- 完成原调用方注册的业务逻辑。如果非阻塞函数本身不存储任务的result,那么callback function一般需要基于result执行业务逻辑。这时,callback function是需要参数的,它的执行逻辑显然需要基于任务的某些关键结果
可以看到,只要callback function需要参数,就存在一个约定好的协议,由非阻塞函数根据这个协议在调用callback时传参
参数越多,协议就越复杂越隐式
如果callback不需要任何参数,那么它回传给主调的信息其实和任务本身毫无关联,这是没有价值的。因此,推荐callback使用一个参数承接task result并回传
callback的样例
function greeting(name) {
alert(`Hello, ${name}`);
}
function processUserInput(callback) {
const name = prompt("Please enter your name."); // js的await内部实现了事件完成时接收通知的机制,对程序员不可见,从而让我们可以通过同步的【形式】实现异步逻辑的效果
callback(name);
}
processUserInput(greeting);
网友评论