由于javascript是单线程的执行模型,因此为了提高效率就有了异步编程,单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。 但是我们也需要类似多线程机制的这种执行方式,我们需要异步执行编程,异步执行编程会使得多个任务并发执行。 异步编程可以实现多任务并发执行,指同一时刻内多任务同时进行,边煮饭,边烧水,可以同时进行,进而提高效率。
1.回调函数
回调函数,就是把任务的第二段单独写在一个函数里面,等到重新执行这个任务的时候,就直接调用这个函数。
const fs = require('fs')
fs.readFile('/etc/passwd', (err, data) => {
if (err) {
console.error(err)
return
}
console.log(data.toString())
})
回调函数最大的问题是容易形成回调地狱,即多个回调函数嵌套,降低代码可读性,增加逻辑的复杂性,容易出错。
fs.readFile(file1, function (err, data) {
fs.readFile(file2, function (err, data) {
//
})
})
2.promise
为解决回调函数的不足,就有了Promise。
const fs = require('fs')
const readFileWithPromise = file => {
return new Promise((resolve, reject) => {
fs.readFile(file, (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
readFileWithPromise('/etc/passwd')
.then(data => {
console.log(data.toString())
return readFileWithPromise('/etc/profile')
})
.then(data => {
console.log(data.toString())
})
.catch(err => {
console.log(err)
})
promise 实际上是利用编程技巧将回调函数的横向加载,改成纵向加载,达到链式调用的效果,避免回调地狱。最大问题是代码冗余,原来的任务被 promise 包装了一下,优点是减少代码嵌套,代码逻辑清晰。
3.async、await
为了解决 promise 的问题,async、await 在 ES7 中被提了出来
const fs = require('fs')
async function readFile() {
try {
var f1 = await readFileWithPromise('/etc/passwd')
console.log(f1.toString())
var f2 = await readFileWithPromise('/etc/profile')
console.log(f2.toString())
} catch (err) {
console.log(err)
}
}
特点:
1.异步async函数的调用,跟普通的函数使用方式一样;
2.async的用法,它作为一个关键字放到函数前面,这样普通函数就变成了异步函数;
3.异步async函数返回一个promise对象;
4.async函数配合await使用可以阻塞代码往下执行,是异步方法。
优点:
1.多个参数传递:promise使用then函数只能传递一个参数,虽然可以通过包装成对象来传递多个参数,但是会导致传递冗余信息,频繁的解析又重新组合比较麻烦;而利用async和await可以没有这个限制,可以当做普通变量的局部变量来处理,也没有冗余工作;
2.同步和异步一起编写:使用promise的时候最好将同步代码和异步代码放在不同的then节点中,这样结构更加清晰;async和await整个书写习惯都是同步的,不需要纠结同步和异步的区别,当然,异步过程需要包装成一个promise对象放在await关键字后面;
3. 对promise的优化:async和await是基于promise的,是进一步的一种优化。
使用场景:
async和await主要用来处理异步的 *** 作,执行第一步,将执行第一步的结果返回给第二步使用,在ajax中先拿到一个接口的返回数据,后使用第一部返回的数据执行第二步 *** 作的接口调用,达到异步 *** 作。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)