promise介绍
- ES6教程传送门:http://es6.ruanyifeng.com/#docs/promise
- Promise是什么?
- Promise是一个构造函数,用于创建Promise对象
- Promise对象:可以理解为一个处理异步操作的容器
- Promise是一个构造函数,用于创建Promise对象
- promise本质
不是控制异步代码的执行顺序(无法控制) , 而是控制异步代码结果处理的顺序
- Promise作用:解决回调地狱
- 回调地狱:异步回调层层嵌套
promise使用
- 使用流程
- 创建promise实例对象
let p = new Promise( (resolve,reject)=>{
//异步操作 } )
- 调用实例对象的then方法
p.then(data=>{
//处理成功数据 } , err=>{ //处理失败结果 })
- promise有三种状态
- pending(进行中)
- fulfilled(已成功)
- rejected(已失败)
- Promise状态改变只有两种情况(过程不可逆)
- 从
pending
(进行中)变为fulfilled
(成功) - 从
pending
(进行中)变为rejected
(失败)
- 从
- 注意点
- Promise对象在创建的时候,里面的异步就会立即执行
- 不要在创建promise的时候处理异步结果,应该调用resolve()或者reject()交给then()方法来处理
- promise解决回调地狱 : 在上一个promise的then方法中返回下一个promise实例对象
需求:依次读取abcd四个文件
const fs = require('fs');
//Promise是一个构造函数,用于创建promise实例
//(1)调用Promise构造函数,生成promise实例对象
/*
参数:回调函数 (resolve,reject)=>{ //你想要的异步操作 }
resolve : 完成回调
reject : 失败回调
*/
let p1 = new Promise((resolve, reject) => {
//异步操作: 读取文件a
fs.readFile(`${
__dirname}/data/a.txt`, 'utf8', (err, data) => {
if (!err) {
//成功
/*
(1)resolve:执行then方法里面的第一个函数
(2)resolve底层原理:修改promise状态从pending(进行中)变为fulfilled(成功)
*/
resolve(data);
} else {
//失败
/*
(1)reject:执行then方法里面的第二个函数
(2)rreject底层原理:修改promise状态从pending(进行中)变为rejected(失败)
*/
reject(err);
}
});
});
let p2 = new Promise((resolve, reject) => {
//异步操作: 读取文件a
fs.readFile(`${
__dirname}/data/b.txt`, 'utf8', (err, data) => {
if (!err) {
//成功
resolve(data);
} else {
//失败
reject(err);
}
});
});
let p3 = new Promise((resolve, reject) => {
//异步操作: 读取文件a
fs.readFile(`${
__dirname}/data/c.txt`, 'utf8', (err, data) => {
if (!err) {
//成功
resolve(data);
} else {
//失败
reject(err);
}
});
});
let p4 = new Promise((resolve, reject) => {
//异步操作: 读取文件a
fs.readFile(`${
__dirname}/data/d.txt`, 'utf8', (err, data) => {
if (!err) {
//成功
resolve(data);
} else {
//失败
reject(err);
}
});
});
//(2)调用promise实例的then方法
//第一个参数: 成功的回调
//第二个参数: 失败的回调
p1.then(data=>{
console.log(data);
return p2;//在第一个promise的then方法中返回第二个promise对象
})
.then(data=>{
//p2的then
console.log(data);
return p3;
})
.then(data=>{
//p3的then
console.log(data);
return p4;
})
.then(data=>{
//p4的then
console.log(data);
});
- promise本质不是修改异步的顺序(异步永远是无序的),而是通过控制异步结果的顺序,从而实现异步代码有序执行。
Promise的方法
- catch():捕捉then方法中的错误err
- all():将多个Promise对象放入数组合并成一个promise
- 要等所有的promise全部执行完毕才会执行then() : 逻辑与
- race() :将多个promise对象放入数组中合并成一个promise
- race: 任何一个promise执行完毕就会执行then() : 逻辑或
/* 需求 : 依次读取abcd四个文件
*/
const fs = require('fs');
//Promise是一个构造函数,用于创建promise实例
//封装一个创建promise的函数
function createPromise(filename){
return new Promise((resolve,reject)=>{
fs.readFile(`${
__dirname}/data/${
filename}.txt`, 'utf8', (err, data) => {
if (!err) {
//成功
resolve(data);
} else {
//失败
reject(err);
}
});
});
};
let p1 = createPromise('a');
let p2 = createPromise('b');
let p3 = createPromise('c');
let p4 = createPromise('d');
//(2)调用promise实例的then方法
//第一个参数: 成功的回调
//第二个参数: 失败的回调
p1.then(data=>{
console.log(data);
return p2;//在第一个promise的then方法中返回第二个promise对象
})
.then(data=>{
//p2的then
console.log(data);
return p3;
})
.then(data=>{
//p3的then
console.log(data);
return p4;
})
.then(data=>{
//p4的then
console.log(data);
})
.catch(err=>{
//catch : 上面任何一个then出错了都会进入这个方法
console.log(err);
});
//all()方法
//Promise.all([p1,p2,p3,p4]) : 多个promise合成一个
let pAll = Promise.all([p1,p2,p3,p4]);
//(2)调用promise实例的then方法
pAll.then(data=>{
//执行时机: pAll中所有的promise全部都完成才会执行then
//data : 数组。 数组中每一个元素就是每一个promise的结果
console.log(data);
});
//race方法
```js
//Promise.all([p1,p2,p3,p4]) : 多个promise合成一个
let pAll = Promise.race([p1,p2,p3,p4]);
//(2)调用promise实例的then方法
pAll.then(data=>{
//执行时机: pAll中 任何一个 promise完成就会执行then
//data : 第一个执行完毕的promise的结果
console.log(data);
});
数组降维
数组降维就是把一个二维数组变成一维数组
方式一:数组的concat()拼接数组
/*
二维数组 : 数组每一个元素都是一个数组
*/
let arr = [
['a', 'b', 'c'],
['d', 'e', 'f'],
['g', 'h', 'i'],
];
console.log(arr);
// 降维;
//方式一:数组的concat()拼接数组
let newArr = [];
for (let i = 0; i < arr.length; i++) {
newArr = newArr.concat(arr[i]);
}
console.log(newArr);
方式二:ES6拓展运算符
二维数组 : 数组每一个元素都是一个数组
*/
let arr = [
['a', 'b', 'c'],
['d', 'e', 'f'],
['g', 'h', 'i'],
];
console.log(arr);
//方式二:使用ES6的拓展运算符 ...
let newArr = [];
for (let i = 0; i < arr.length; i++) {
newArr.push(...arr[i]);
}
console.log(newArr);
数组升维
一维数组生成二维获者多维
- 利用对象的特点实现数组去重
对象特点
obj.name 取值 : 有:取值 没有:undefined
obj.name = 1 赋值 : 有:修改 没有:动态添加
对象的属性名不能重复
let arr1 = [88, 20, 66, 50, 90, 88, 20, 66];
let obj = {
}; //利用属性名不能重复特点实现数组去重
let newArr = [];
for (let i = 0; i < arr1.length; i++) {
if (!obj[arr1[i]]) {
//!undefined=true obj.name 取值 : 有:取值 没有:undefined
obj[arr1[i]] = 1; // obj.name = 1 赋值 : 有:修改 没有:动态添加
newArr.push(arr1[i]);
}
}
console.log(newArr);
未升维之前的一维数组
升维后的数组