源码阅读06-delay 延迟函数

139 阅读2分钟

我正在参与掘金会员专属活动-源码共读第一期,点击参与

前言

以前面试经历中有遇到过这样的一个面试题使用 promise 实现一个延时函数。一直从事后端开发的人来说,像 C# 、Java 来说直接一个 sleep 方法就能解决。但当时由于是学会 Node 开发不是很久,遇到这样的题目还是一时不知道怎么解决。

源码地址:github.com/sindresorhu…

JS 的延时函数

在 JS 中,应该大部分人都是只要的现有的两个延迟执行函数:

  • setTimeout 只执行一次
  • setInterval 每隔几秒执行,一直执行下去
setTimeout(()=>{
  console.log("hello")
},10000); // /10秒后执行一次,输出 hello。 只执行一次。

setInterval(()=>{
  console.log("hello")
},10000); //每隔10秒执行一次,输出 hello ,一直执行下去

setInterval 方法如果要停止的话,可以是使用 clearInterval 方法就可以完成。但是对于 setTimeout 是 JS 没有提供直接的办法停止延时执行。setTimeout 函数是只执行一次就可以结束,其可以直接看出来是个延迟执行函数。

promise 实现延时

function delay(delaytime){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve();
        }, delaytime);
    });
}

在源码中是基于使用 promise 和 setTimeout 完成一个同步延时的功能。这个就可以回答之前遇到的面试题。

遇到新问题:设立了延时但是由于某原因想终止延时执行时,如何终止?

因为没有其他可以直接停止的函数,所以可以终止setTimeout 的触发。那么就需要外面参数控制,告知是终止还是继续。

function delay(delaytime, willResolve){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
          if(willResolve){
            resolve();
             } else {
             reject();
         }
        }, delaytime);
     
    });
}

这也是源码 delay 函数的核心方法。因为在 createDelay 时返回结果是 delayPromise 对象。所以整个过程其实很简单的完成延时函数。在项目中执行了结果,可以很好证明了这个方法的封装。

在源码中还通过加入将上面resolve 和 reject 控制封装成函数 settle,整个延时函数赋值给 全局的timeoutId,这样在清除延时器的时候只需要从 delayPromise.clear 上执行。

看着很简单的源码,其中用的很多语法方式自己从来没遇到。还需要学习的东西很多。坚持读源码真的会受益匪浅。