Node.js 入门教程
Node.js中文网
本文仅用于学习记录,不存在任何商业用途,如侵删
文章目录
29 了解 process.nextTick()
当尝试了解 Node.js 事件循环时,其中一个重要的部分就是 process.nextTick()
。
每当事件循环进行一次完整的行程时,我们都将其称为一个滴答。
当将一个函数传给 process.nextTick()
时,则指示引擎在当前操作结束(在下一个事件循环滴答开始之前)时调用此函数:
process.nextTick(() => {
//做些事情
})
事件循环正在忙于处理当前的函数代码。
当该操作结束时,JS 引擎会运行在该操作期间传给 nextTick
调用的所有函数。
这是可以告诉 JS 引擎异步地(在当前函数之后)处理函数的方式,但是尽快执行而不是将其排入队列。
调用 setTimeout(() => {}, 0)
会在下一个滴答结束时执行该函数,比使用 nextTick()
(其会优先执行该调用并在下一个滴答开始之前执行该函数)晚得多。
当要确保在下一个事件循环迭代中代码已被执行,则使用 nextTick()
。【懵圈】
30 了解 setImmediate()
当要异步地(但要尽可能快)执行某些代码时,其中一个选择是使用 Node.js 提供的 setImmediate()
函数:
setImmediate(() => {
//运行一些东西
})
作为 setImmediate() 参数传入的任何函数都是在事件循环的下一个迭代中执行的回调。
setImmediate()
与 setTimeout(() => {}, 0)
(传入 0 毫秒的超时)、process.nextTick()
有何不同?
传给 process.nextTick()
的函数会在事件循环的当前迭代中(当前操作结束之后)被执行。 这意味着它会始终在 setTimeout
和 setImmediate
之前执行。
延迟 0 毫秒的 setTimeout()
回调与 setImmediate()
非常相似。 执行顺序取决于各种因素,但是它们都会在事件循环的下一个迭代中运行。
31 探索 JavaScript 定时器
31.1 setTimeout()
当编写 JavaScript 代码时,可能希望延迟函数的执行。
这就是 setTimeout 的工作。 指定一个回调函数以供稍后执行,并指定希望它稍后运行的时间(以毫秒为单位)的值:
setTimeout(() => {
// 2 秒之后运行
}, 2000)
setTimeout(() => {
// 50 毫秒之后运行
}, 50)
该语法定义了一个新的函数。 可以在其中调用所需的任何其他函数,也可以传入现有的函数名称和一组参数:
const myFunction = (firstParam, secondParam) => {
// 做些事情
}
// 2 秒之后运行
setTimeout(myFunction, 2000, firstParam, secondParam)
setTimeout
会返回定时器的 id。
通常不使用它,但是可以保存此 id,并在要删除此安排的函数执行时清除它:
const id = setTimeout(() => {
// 应该在 2 秒之后运行
}, 2000)
// 改变主意了
clearTimeout(id)
31.2 零延迟
如果将超时延迟指定为 0
,则回调函数会被尽快执行(但是是在当前函数执行之后):
setTimeout(() => {
console.log('后者 ')
}, 0)
console.log(' 前者 ')
会打印 前者 后者
。
通过在调度程序中排队函数,可以避免在执行繁重的任务时阻塞 CPU,并在执行繁重的计算时执行其他函数。
某些浏览器(IE 和 Edge)实现的
setImmediate()
方法具有相同的确切功能,但是不是标准的,并且在其他浏览器上不可用。但是在 Node.js 中它是标准的函数。
31.3 setInterval()
setInterval
是一个类似于 setTimeout
的函数,不同之处在于:它会在指定的特定时间间隔(以毫秒为单位)一直地运行回调函数,而不是只运行一次:
setInterval(() => {
// 每 2 秒运行一次
}, 2000)
上面的函数每隔 2 秒运行一次,除非使用 clearInterval
告诉它停止(传入 setInterval
返回的间隔定时器 id):
const id = setInterval(() => {
// 每 2 秒运行一次
}, 2000)
clearInterval(id)
通常在 setInterval
回调函数中调用 clearInterval
,以使其自行判断是否应该再次运行或停止。 例如,此代码会运行某些事情,除非 App.somethingIWait
具有值 arrived
:
const interval = setInterval(() => {
if (App.somethingIWait === 'arrived') {
clearInterval(interval)
return
}
// 否则做些事情
}, 100)
31.4 递归的 setTimeout
setInterval
每 n 毫秒启动一个函数,而无需考虑函数何时完成执行。
如果一个函数总是花费相同的时间,那就没问题了:
函数可能需要不同的执行时间,这具体取决于网络条件,例如:
也许一个较长时间的执行会与下一次执行重叠:
为了避免这种情况,可以在回调函数完成时安排要被调用的递归的 setTimeout:
const myFunction = () => {
// 做些事情
setTimeout(myFunction, 1000)
}
setTimeout(myFunction, 1000)
实现此方案:
setTimeout
和 setInterval
可通过定时器模块在 Node.js 中使用。
Node.js 还提供 setImmediate()
(相当于使用 setTimeout(() => {}, 0)
),通常用于与 Node.js 事件循环配合使用。