setInterval 模拟 setTimeout

  1. function mySetTimeout(fn, time) {
  2. let timer = null
  3. function timeout() {
  4. fn()
  5. clearInterval(timer)
  6. }
  7. timer = setInterval(timeout, time)
  8. return {
  9. cancel: () => clearInterval(timer)
  10. }
  11. }
  12. var result = mySetTimeout(() => {
  13. console.log('mySetTimeout')
  14. }, 3000)
  15. setTimeout(() => {
  16. result.cancel()
  17. // console.log('提前执行了清空')
  18. console.log('延后执行了清空')
  19. }, 4000)

setTimeout 模拟 setInterval

  1. function myInterval(fn, time) {
  2. let timer = null, isClear = false;
  3. function interval() {
  4. if (isClear) {
  5. isClear = false
  6. clearTimeout(timer)
  7. return
  8. }
  9. fn()
  10. timer = setTimeout(interval, time)
  11. // console.log('timer - 1', timer)
  12. }
  13. timer = setTimeout(interval, time)
  14. // console.log('timer - 2', timer)
  15. // 返回一个清空定时器方法
  16. return {
  17. cancel: () => isClear = true
  18. }
  19. }
  20. let count = 0;
  21. let result = myInterval(() => {
  22. count++
  23. console.log('1 - myInterval', count)
  24. if (count === 3) {
  25. result.cancel()
  26. }
  27. }, 3000)

思路:

  1. 两个变量timerclear来存放当前定时器 ID,和清空定时器开关;
  2. 声明 interval函数(重点),用来模拟setInterval
  3. 触发interval函数执行,需要setTimeout
  4. 返回清空定时器方法:cancel

注意:**timer**值是一直变的,需要取到最后一个**timer**值,用来清空最后一个定时器。

  1. // 法二:
  2. function myInterval(fn, time) {
  3. let timer = null;
  4. function interval() {
  5. timer = setTimeout(interval, time)
  6. fn(timer)
  7. // console.log('timer - 1', timer)
  8. }
  9. timer = setTimeout(interval, time)
  10. // console.log('timer - 2', timer)
  11. return {
  12. cancel: (t) => clearTimeout(t)
  13. }
  14. }
  15. let count = 0;
  16. let result = myInterval((timer) => {
  17. count++
  18. // console.log('timer - 3', timer)
  19. if (count === 3) {
  20. result.cancel(timer)
  21. }
  22. }, 3000)

requestAnimationFrame 模拟 setInterval

  1. function setInterval(callback, interval) {
  2. let timer
  3. const now = Date.now
  4. let startTime = now()
  5. let endTime = startTime
  6. const loop = () => {
  7. timer = window.requestAnimationFrame(loop)
  8. endTime = now()
  9. if (endTime - startTime >= interval) {
  10. startTime = endTime = now()
  11. callback(timer)
  12. }
  13. }
  14. timer = window.requestAnimationFrame(loop)
  15. return timer
  16. }
  17. let a = 0
  18. setInterval(timer => {
  19. console.log(1)
  20. a++
  21. if (a === 3) cancelAnimationFrame(timer)
  22. }, 1000)