setTimeout原来是这样工作的

in JavaScript with 0 comment

众所周知,js是单线程,同dom操作,事件一样setTimeout是异步执行的,都属于宏任务,是放在宏任务队列中执行的,setTimeout(callback, delay, args...) 的第二个参数delay表示的函数并不是到了delay的时间执行,而delay真正的意思是将回调函数加入任务队列的时间, 也即表示任务执行的最小时间 minimum delay, 因为js要先执行完主线程上的任务,然后执行完异步队列靠前的任务,当所有这些任务执行完成后才去执行添加的异步任务。

见stackoverflow上的回答

第三个参数及以后表示一旦定时器到期,它们会作为参数传递callback这个回调函数

function getAge(a, ...args) {
  console.log(args)
}
setTimeout(getAge, 2000, 29, 33, 44, 99)

使用控制台测试js程序执行时间

console.time('sort')
//+一元运算符,会找对象的 valueOf()或 toString()方法
//new Date().valueOf() 打印时间戳
console.log(+new Date())
for(var i = 0; i < 15000; i++) {
  console.log('A')
}
console.timeEnd('sort')
console.log(+new Date())

setTimeout做进度条

function handle() { 
  let a = 0
  let d = document.getElementById('progress')
  d.style.background = 'red'
  ;(function run(){
    d.innerHTML = a
    d.style.width = a + '%'
     if(a++ < 100) {
       setTimeout(() => {
        run()
       }, 100)
     }
  })()
}
window.onload = function() {
  handle()
}

大数累加

 function sum(num) {
   return new Promise((resolve, reject) => {
    let res = 0
     //把sum包装成宏任务
     setTimeout(() => {
       for(let i = 0; i < num; i++ ){
         res += 1
       }
       resolve(res)
     })
     
   })
 }

//直接使用
sum(338849392).then(res => {
  console.log(res)
})

//使用async/await
 async function test() {
   //sum宏任务
   let result = await sum(3388493920)
   console.log(result)
 }
test()


//把sum计算包装成微任务,放到then语句块(异步执行)
 async function test1(num) {
   let res = 0
   let result = await Promise.resolve().then(() => {
      for(let i = 0; i < num; i++ ){
          res += 1
      }
      //这里可以直接返回,这里返回的值即为await等待的值
      return res
   })
   console.log(result)
 }
 test1(338849390)
 console.log('同步任务')

评论已关闭.