事件循环这里就不详细描述了,如果不太了解可以看看前端–事件循环机制
下面是node官网提供的一个示例。
const bar = () => console.log('bar')
const baz = () => console.log('baz')
const foo = () => {
console.log('foo')
setTimeout(bar, 0)
new Promise((resolve, reject) =>
resolve('应该在 baz 之后、bar 之前')
).then(resolve => console.log(resolve))
baz()
}
foo()
打印结果
foo
baz
应该在 baz 之后、bar 之前
bar
可以在nodejs的REPL环境中或任何模块中访问process对象。
可以将process对象称为进程对象,即nodejs进程对象。
**process.nextTick( callback )**方法用于将一个函数推迟到代码中所书写的下一个同步方法执行完毕时或异步方法的事件回调函数开始执行时调用,该方法中使用一个参数,参数值是被推迟的函数。
作为 setImmediate() 参数传入的任何函数都是在事件循环的下一个迭代中执行的回调。
console.log('同步11------')
setImmediate(() => {
//运行一些东西
console.log('setImmediate执行--------')
})
setTimeout(()=>{
console.log('setTimeout执行-----------')
},0)
process.nextTick(() => {
//做些事情
console.log('process执行 ---------- ')
})
console.log('同步2--------')
我们能发现process.nextTick是在所有当前事件循环同步方法后,下一个事件循环前 执行。
setImmediate() 与延迟 0 毫秒的 setTimeout() 回调 非常相似。
Promise 通常被定义为最终会变为可用值的代理。
Promise 是一种处理异步代码(而不会陷入回调地狱)的方式。
fetch('https://api.github.com/users/github')
.then(status) // 注意,`status` 函数实际上在这里被调用,并且同样返回 promise,
.then(json) // 这里唯一的区别是的 `json` 函数会返回解决时传入 `data` 的 promise,
.then(data => { // 这是 `data` 会在此处作为匿名函数的第一个参数的原因。
console.log('请求成功获得 JSON 响应', data)
})
.catch(error => {
console.log('请求失败', error)
})
它们减少了 promises 的样板,且减少了 promise 链的“不破坏链条”的限制。
当 ES2015 中引入 Promise 时,它们旨在解决异步代码的问题,并且确实做到了,但是在 ES2015 和 ES2017 断开的两年中,很明显,promise 不可能成为最终的解决方案。
Promise 被引入了用于解决著名的回调地狱问题,但是它们自身引入了复杂性以及语法复杂性。
它们是很好的原语,可以向开发人员公开更好的语法,因此,当时机合适时,我们得到了异步函数。
它们使代码看起来像是同步的,但它是异步的并且在后台无阻塞。
const doSomethingAsync = () => {
return new Promise(resolve => {
setTimeout(() => resolve('做些事情'), 3000)
})
}
const doSomething = async () => {
console.log(await doSomethingAsync())
}
console.log('之前')
doSomething()
console.log('之后')
Node.js 也提供了使用 events 模块构建类似系统的选项。
具体上,此模块提供了 EventEmitter 类,用于处理事件。
该对象公开了 on 和 emit 方法。
const EventEmitter = require('events')
const eventEmitter = new EventEmitter()
eventEmitter.on('start', (e) => {
console.log(e,'开始')
})
eventEmitter.emit('start',34)