延迟执行的函数defer

 /**
     * 创建延迟指定时间后执行的函数fn, 如果在延迟时间内再次执行该方法, 将会根据指定的exclusion的值,
     * 决定是否取消前一次函数的执行, 如果exclusion的值为true, 则取消执行,反之,将继续执行前一个方法。
     * @method defer
     * @param { Function } fn 需要延迟执行的函数对象
     * @param { int } delay 延迟的时间, 单位是毫秒
     * @param { Boolean } exclusion 如果在延迟时间内再次执行该函数,该值将决定是否取消执行前一次函数的执行,
     *                     值为true表示取消执行, 反之则将在执行前一次函数之后才执行本次函数调用。
     * @warning 该方法的时间控制是不精确的,仅仅只能保证函数的执行是在给定的时间之后,
     *           而不能保证刚好到达延迟时间时执行。
     * @return { Function } 目标函数fn的代理函数, 只有执行该函数才能起到延时效果
     * @example
     * ```javascript
     *
     * function test(){
     *     console.log(1);
     * }
     *
     * var testDefer = defer( test, 1000, true );
     *
     * //output: (两次调用仅有一次输出) 1
     * testDefer();
     * testDefer();
     * ```
     */
function  defer(fn, delay, exclusion) {
        var timerID;
        return function () {
            if (exclusion) {
                clearTimeout(timerID);
            }
            timerID = setTimeout(fn, delay);
     };
### 使用方法 Go 语言提供了 `defer` 关键字,可以注册多个延迟调用,这些调用以先进后出(FILO)的顺序在函数返回前被执行,有点类似 Java 语言中异常处理里的 `finally` 子句。`defer` 语句会立刻计算参数,但延迟函数体的执行 [^4][^5]。 示例代码如下: ```go package main import "fmt" func main() { defer fmt.Println("world") fmt.Println("hello") } ``` 上述代码会先输出 `hello`,再输出 `world`。另一个例子: ```go package main func main() { // 先进后出 defer func() { println("first") }() defer func() { println("second") }() println("function body") } ``` 该代码的输出结果为: ``` function body second first ``` ### 原理 从底层来看,`defer` 有“注册 - 执行”的全生命周期。`defer` 语句会在当前函数栈帧上创建一个 `defer` 结构体来记录要执行函数和相关参数,这个过程就是“注册”。而在函数返回前,会按照先进后出的顺序依次执行这些 `defer` 函数,这就是“执行” [^2]。 ### 应用场景 - **资源释放**:常用于保证一些资源最终一定能够得到回收和释放。例如文件操作时,使用 `defer` 确保文件在函数结束时关闭: ```go package main import ( "fmt" "os" ) func main() { filename := "test.txt" f, err := os.Open(filename) if err != nil { panic(err) } if f != nil { defer f.Close() } // 对文件进行操作 fmt.Println("文件操作完成") } ``` - **锁的释放**:在使用互斥锁时,使用 `defer` 可以确保锁在函数结束时被释放,避免死锁: ```go package main import ( "fmt" "sync" ) var ( mu sync.Mutex count int ) func increment() { mu.Lock() defer mu.Unlock() count++ fmt.Println("Count:", count) } func main() { increment() } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值