promise语法与事件循环EVent Loop
1.promise
在为引入promise之前,函数的调用多为嵌套形式,当嵌套的内容过多就会造成回调地狱。如下方例子所示:
//在回调函数中嵌套执行
//弊端 : 形成回调地狱(异步回调 层层嵌套,非常麻烦且不便于维护)
//读取文件A
const fs = require('fs')
fs.readFile("./data/a.txt", 'utf-8', (err, data) => {
if (err) {
console.log(err);
} else {
console.log(data);
//A读取成功之后开始读取B
fs.readFile("./data/b.txt", 'utf-8', (err, data) => {
if (err) {
console.log(err);
} else {
console.log(data);
//B读取成功之后开始读取C
fs.readFile("./data/c.txt", 'utf-8', (err, data) => {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
}
});
}
});
所以自从引入了promise之后可以用过promise进行解决回调地域问题。首先先了解什么是promise及其作用。
promise的基本使用
1.实例化Promise对象
作用: 将异步操作代码 放入 Promise中
resolve:异步操作 成功状态
reject : 异步操作 失败状态
new Promise((resolve,reject)=>{ 你的异步操作 })
2.调用then()方法处理异步操作结果
promise对象.then((data)=>{ 处理成功数据 },(err)=>{ 处理失败信息 });
上方代码利用promise:
/*
1.Promise是一个构造函数 , 返回一个Promise对象
2.使用流程
(1)实例化Promise对象 : 将异步操作放入Promise中
(2)调用then() 方法: 处理异步操作结果
*/
const fs = require('fs')
//1.创建promise实例对象
const p1 = new Promise((resolve, reject) => {
//异步操作
fs.readFile('./data/a.txt', 'utf8', (err, data) => {
if (err) {
/*
(1)异步操作失败,则执行 reject()
(2)reject会把把promise对象的状态从 pending进行中 改为 rejected失败
(3)该方法本质是调用 then() 中的第二个方法
*/
reject(err)
} else {
/*
(1)异步操作成功,则执行 resolve()
(2)resolve会把把promise对象的状态从 pending进行中 改为 fulfilled成功
(3)该方法本质是调用 then() 中的第一个方法
*/
resolve(data)
}
})
})
//2. p1.then() : 处理异步操作结果
p1.then(data => {
//成功
console.log(data)
}).catch(err => {
//失败
console.log(err)
})
promise特点:
promise本质 不是控制
异步代码的执行顺序
(无法控制) , 而是控制
异步代码结果处理的顺序
promise本身只是一个容器,真正异步的是它的两个回调resolve()和reject()
但是上方的代码仍然过于复杂所以引入了promise的all方法,进行代码的优化。
all
-
将多个Promise合并成一个Promise
-
所有异步全部执行完毕才会执行then方法
-
const fs = require('fs') //1.创建promise实例对象 function promise(name) { return new Promise((resolve, reject) => { //异步操作 fs.readFile(`./data/${name}.txt`, 'utf8', (err, data) => { if (err) { reject(err) } else { resolve(data) } }) }) } //2.解决需求: a , b , c 同时执行完毕 const p1 = promise('a') const p2 = promise('b') const p3 = promise('c') //将三个异步操作合并成一个Promise const pAll = Promise.all([p1, p2, p3]) //开始读取a // 三个promise都成功后,才去执行pAll.then的第一个方法. // 只要有一个失败了,就去执行catch里面的函数. pAll.then((data) => { console.log(data) //data是一个数组,存储每一个promise的成功结果 }).catch(err => { console.log(err) })
什么是回调地狱?
回调地狱:在回调函数中再嵌套回调函数的情况称为回调地狱(是实现代码顺序执行的一种操作方式)
(1)代码的可读性差、可维护性差
(2)代码的扩展性差
解决回调地狱问题
回调地狱的问题:
.嵌套层次很深,可读性差,难以维护
.无法正常使用return 和throw
.多个回调之间难以建立联系
回调地狱的解决办法:
(1)Promise
(2)async/await文章来源:https://www.toymoban.com/news/detail-448044.html
2.事件循环:
什么是事件循环:
js是一个单线程的。函数执行的过程是将函数执行上下文压入栈中,直到栈中清空,表示这个任务执行结束。为了保证异步的函数按顺序执行,出现了task queue(任务队列)。任务队列的作用是将各种事件或异步的操作进行通知时加入其回调函数。js引擎会不停的从任务队列中取出任务,压入到栈中执行,执行完成后再取下一个任务执行,如此一直到任务队列为空。如果为空,会一直等待新的任务出现。这种不停的等待处理事件的循环称之为事件循环。文章来源地址https://www.toymoban.com/news/detail-448044.html
到了这里,关于js2.0的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!