es6-promise学习与使用
es6-promise介绍与基本使用
promise是ES6引入的异步编程的新解决方案,语法上市promise是一个构造函数,用来封装异步操作并可以获取奇成功或失败的结果【解决回调地狱问题】
- Promise构造函数 :
Promise {excutor}{ }
-
Promise.prototype.then
方法
-
Promise.prototype.catch
方法
1. 实例化Promise对象
Promise对象有三个状态,初始化,成功,失败
实例化promise对象:
//实例化Promise对象【三个状态:初始化,成功,失败】
const p = new Promise(function(resolve,reject){
setTimeout(() => {
let data = "数据库中的用户数据"
//resolve调用
resolve(data);
}, 1000);
});
调用成功和失败都会执行promise.then的方法,then的方法有两个参数,两个参数都是函数类型的值,每个函数都有一个形参,成功的执行then的第一个函数,失败的执行第二个执行参数,两个函数的形参分别是value和reason,成功的叫做value,失败的叫做reson。
调用then代码:
/*
调用成功,就会调用promise对象的then方法,
then方法接受两个参数,
两个参数都是函数类型的值,每个函数都有一个形参,成功的叫做value,失败的叫做reason
调到resolve代表成功,读取状态成功,then就会执行第一个回调函数代码
如果读取状态失败,调用带有
*/
p.then(
function(value){
console.log(value);
},
function(reason){
}
)
成功调用输出:
读取失败的例子:
const p = new Promise(function(resolve,reject){
setTimeout(() => {
//
let data = "数据库中的用户数据"
let err = "读取数据库失败"
//resolve调用
reject(err)
}, 1000);
});
p.then(function(value){
console.log(value);
},function(reason){
console.log(reason);
})
es6-promise封装读取文件
原生js输出文件内容【请求文件内容属于异步】
//引入fs模块
const fs = require('fs');
//调用方法读取文件
fs.readFile('./resources/1.md',(err,data)=>{
//如果失败则抛出错误
if(err) throw err;
//如果没有出错,则输出内容
console.log(data.toString());
})
效果:
使用promise封装读取文件:
//3.使用promise封装
const p = new Promise(function(resolve,reject){
fs.readFile("./resources/1.md",(err,data)=>{
//判断读取失败
if(err) reject(err);
//如果成功
resolve(data)
})
})
p.then(
function(value){
console.log(value.toString());
},
function(reason){
console.log(reason);
})
效果:
es6-promise封装Ajax请求
- 原生Ajax请求数据
<script>
//接口地址:https://api.apiopen.top/getJoke
//创建对象
const xhr = new XMLHttpRequest();
//初始化
xhr.open("GET","https://api.apiopen.top/getJoke");
//发送
xhr.send();
//4.绑定时间,处理响应结果
xhr.onreadystatechange = function(){
//判断
if(xhr.readyState === 4){
//判断响应状态吗 200-299
if(xhr.status >= 200 && xhr.status < 300){
//表示成功
console.log(xhr.response);
}else{
//如果失败
console.log(xhr.status);
}
}
}
</script>
请求成功效果:
请求失败结果:
2. Promise进行封装Ajax代码
<script>
//接口地址:https://api.apiopen.top/getJoke
const p = new Promise((resolve,reject)=>{
//创建对象
const xhr = new XMLHttpRequest();
//初始化
xhr.open("GET","https://api.apiopen.top/getJoke");
//发送
xhr.send();
//4.绑定时间,处理响应结果
xhr.onreadystatechange = function(){
//判断
if(xhr.readyState === 4){
//判断响应状态吗 200-299
if(xhr.status >= 200 && xhr.status < 300){
//表示成功
resolve(xhr.response)
}else{
//如果失败
reject(xhr.status);
}
}
}
});
//指定回调
p.then(
function(value){
console.log(value);
},
function(reason){
console.log(reason);
})
</script>
成功效果:
失败效果:
处理方式不一样,原来是在回调函数里面处理成功和失败的结果,promise实在异步任务的后面通过then来指定回调,结构清晰,也不会产生回调地狱的问题。
es6-Promise.prototype.then方法
-
then返回结果:返回结果是由执行函数的回调结果来决定的,如果回调函数中返回的结果是 ||promise类型的属性,状态为成功,返回值为对象的成功值。
-
then返回非Promise对象
//创建promise对象
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
//resolve("请求成功")
reject("请求失败")
},1000)
});
//调用 then方法
const result = p.then(value =>{
console.log(value);
return value;
},reason =>{
console.log(reason);
return reason;
})
console.log(result);
不写return
返回undefined
结果:
3. then返回Promise对象
then返回Promise对象,then中promise的状态就决定了then方法返回的一个对象的状态,then中Promise的失败就决定了then方法返回的一个失败的状态。
//创建promise对象
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("请求成功")
//reject("请求失败")
},1000)
});
//调用 then方法
const result = p.then(value =>{
return new Promise((resolve,reject)=>{
resolve('ok')
})
},reason =>{
console.log(reason);
})
console.log(result);
4. then抛出错误
【如果抛出错误的话,这个状态也是一个失败的Promise状态,错误的值就是抛出的值】
//创建promise对象
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("请求成功")
//reject("请求失败")
},1000)
});
//调用 then方法
const result = p.then(value =>{
//抛出错误
throw new Error("出错啦")
},reason =>{
console.log(reason);
})
console.log(result);
效果:
既然then的方法可以返回promise对象,所以说then方法可以链式调用,链式调用[then方法指定回调的时候是可以只指定一个的,可以通过链式调用来改变回调地狱的问题]
格式:
p.then(value=>{
//异步任务
},reason=>{
//异步任务
}).then(value=>{
//异步任务
},reason=>{
//异步任务
})
es6-promise实践练习-多个文件内容读取
//回调地狱容易重名,很不容易被发现
- 使用回调地狱方式来做
//引入fs模块
const fs = require("fs")
fs.readFile('./resources/1.md',(err,data)=>{
fs.readFile('./resources/2.md',(err,data1)=>{
fs.readFile('./resources/3.md',(err,data2)=>{
let result = data+"\r\n"+data1+"\r\n"+data2
console.log(result);
});
});
});
上面代码可以发现 ,回调地狱容易重名,很不容易被发现。
Promise实现:
//使用promise来实现
const p = new Promise((resolve,reject)=>{
fs.readFile("./resources/1.md",(err,data)=>{
resolve(data);
})
})
p.then(value=>{
return new Promise((resolve,reject)=>{
fs.readFile("./resources/2.md",(err,data)=>{
resolve([value,data]);
});
});
}).then(value=>{
return new Promise((resolve,reject)=>{
fs.readFile("./resources/3.md",(err,data)=>{
//压入
value.push(data);
resolve(value)
});
});
}).then(value=>{
console.log(value.join('\r\n'));
})
es6-Promise对象catch方法
catch用来指定promise失败的一个回调
第一种方式代码:
<script>
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
//设置p对象的状态为失败,并且设置失败的值
reject("出错啦")
})
})
p.then(function(value){
},function(reason){
console.error(reason);
})
</script>
效果:
第二种方式代码:
<script>
const p = new Promise((resolve,reject)=>{
setTimeout(()=>{
//设置p对象的状态为失败,并且设置失败的值
reject("出错啦")
})
})
p.catch(function(reason){
console.warn(reason);
})
</script>
完结