promise !!!
异步回调地狱
简介
es6出了一个新技术叫promise,主要就是用来解决异步回调地狱的
语法!!!
// 1. 创建promise对象 const p = new Promise(一个实参 函数类型 有两个形参) 第一个形参代表成功了 success resolve 第二个形参代表失败了 error reject const p = new Promise((resolve, reject) => { // console.log('代码默认触发 正在进行中' ) // 写代码 成功了 resolve(数据) 交给then的第一个实参处理 一般放接口返回的数据 // 写代码 失败了 reject(数据) 交给then的第二个实参处理 一般放错误信息 也可以交给全局处理catch }) // 2. 使用 p .then(data => { data就是resolve传递的数据 return 值 // 第一个then返回的值会交给第二个then继续处理 }, err => { // err就是reject的传递的参数 }) .... .then(实参1, 实参2) .catch(err => { // then有第二个实参就自己处理,没有就交给全局catch处理 })
练习
目的:验证我们对语法的理解是不是正确的
明确:new Promise实战函数中一般写异步的代码 ajax、定时器
验证:
a. 验证promise实参函数默认会触发
b. 验证成功了会交给then的第一个实参处理
c. 验证失败了会交给then的第二个实参处理
d. 验证第一个then返回的值会交给第二个then处理
e. 验证失败了如果没写then的第二个实参会交给全局的catch处理
接口准备
{
"meta": {
"msg": "gun",
"statu": 200
},
"data": null
}
环境部署好后
a. 验证promise实参函数默认会触发
<meta charset="UTF-8">
<script>
const p = new Promise((resolve, reject) => { // 回调函数传递进去必定触发
console.log('promise默认触发进行中....')
})
</script>
b. 验证成功了会交给then的第一个实参处理
<meta charset="UTF-8">
<script>
const p = new Promise((resolve, reject) => { // 回调函数传递进去必定触发
console.log('promise默认触发进行中....')
// 1. 创建ajax对象
const xhr = new XMLHttpRequest
// 2. 监控请求状态
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
// 之前:callback处理
// 现在:resolve交给then的第一个实参处理
resolve(JSON.parse(xhr.responseText))
} else {
reject(xhr.status)
}
}
}
// 3. 设置请求地址、请求方式
// xhr.open('get', './api.json')
xhr.open('get', './tishi.json')
// 4. 发送请求
xhr.send(null)
})
p
.then(
res => {
console.log(1, res)
// return undefined
return res
},
err => {
console.log(2, err)
}
)
</script>
c. 验证失败了会交给then的第二个实参处理
<meta charset="UTF-8">
<script>
const p = new Promise((resolve, reject) => { // 回调函数传递进去必定触发
console.log('promise默认触发进行中....')
// 1. 创建ajax对象
const xhr = new XMLHttpRequest
// 2. 监控请求状态
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
// 之前:callback处理
// 现在:resolve交给then的第一个实参处理
resolve(JSON.parse(xhr.responseText))
} else {
reject(xhr.status)
}
}
}
// 3. 设置请求地址、请求方式
// xhr.open('get', './api.json')
xhr.open('get', './jj2.json') //后端接口被修改错误
// 4. 发送请求
xhr.send(null)
})
p
.then(
res => {
console.log(1, res)
// return undefined
return res
},
err => {
console.log(2, err)
}
)
</script>
d. 验证第一个then返回的值会交给第二个then处理
<meta charset="UTF-8">
<script>
const p = new Promise((resolve, reject) => { // 回调函数传递进去必定触发
console.log('promise默认触发进行中....')
// 1. 创建ajax对象
const xhr = new XMLHttpRequest
// 2. 监控请求状态
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
// 之前:callback处理
// 现在:resolve交给then的第一个实参处理
resolve(JSON.parse(xhr.responseText))
} else {
reject(xhr.status)
}
}
}
// 3. 设置请求地址、请求方式
// xhr.open('get', './api.json')
xhr.open('get', './jj.json')
// 4. 发送请求
xhr.send(null)
})
p
.then(
res => {
console.log(1, res)
// return undefined
return res
},
// err => {
// console.log(2, err)
// }
)
.then(res => { // res是第一个then实参的返回值 也就是第一个then结果会交给第二个then处理
console.log(3, res)
})
</script>
d.验证失败了如果没写then的第二个实参会交给全局的catch处理
<meta charset="UTF-8">
<script>
const p = new Promise((resolve, reject) => { // 回调函数传递进去必定触发
console.log('promise默认触发进行中....')
// 1. 创建ajax对象
const xhr = new XMLHttpRequest
// 2. 监控请求状态
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
// 之前:callback处理
// 现在:resolve交给then的第一个实参处理
resolve(JSON.parse(xhr.responseText))
} else {
reject(xhr.status)
}
}
}
// 3. 设置请求地址、请求方式
// xhr.open('get', './api.json')
xhr.open('get', './jj2.json')//接口路径被改错
// 4. 发送请求
xhr.send(null)
})
p
.then(
res => {
console.log(1, res)
// return undefined
return res
},
// err => {
// console.log(2, err)
// }
)
.then(res => { //
console.log(3, res)
})
.catch(err => { //then的第二个实参没写会交给全局的catch处理
console.log(4, err)
})
</script>
■ES7中async/await(扩展)!!!
概念
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,在2015年6月发布
ES2017 标准引入了 async 函数,使得异步操作变得更加方便(解决promise纵向延伸问题)
语法
async function 函数名() { var data = await Promise 对象 ..... }
注意1:
await 操作符用于等待一个 Promise 对象, 它只能在异步函数 async function 内部使用.
注意2:
es5 异步回调地狱瑕疵(横向延伸太深)
es6 promise解决 (竖向延伸太深)
es7 async&await (异步改为同步 一行一行执行)
注意3:
1-await必须和async同时出现
2-await只能和promise一起使用
练习
<meta charset="UTF-8">
<script>
/*
es5 异步回调地狱瑕疵(横)
es6 promise解决 (竖)
es7 async&await (同步 一行一行执行)
语法:
async function 函数名() {
var data1 = await promise对象
var data2 = await promise对象
}
注意:
1-await必须和async同时出现
2-await只能和promise一起使用
*/
function getPromise(method, url) {
var tmp = new Promise(function(s, e){
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
// 打开网站请求成功,并且服务器也响应你内容
if (xhr.readyState == 4)
{
if(xhr.status == 200)
{
s(JSON.parse(xhr.responseText))
} else {
e(JSON.parse(xhr.responseText))
}
}
}
xhr.open(method, url)
xhr.send(null)
})
return tmp
}
async function fn() { //将异步请求改为同步,让代码一行一行执行从而解决异步回调地狱问题
var p1 = await getPromise('get', './jj.json')
console.log(111, p1)
var p2 = await getPromise('get', './jj.json')
console.log(222, p2)
}
// 切记还得调用函数
fn()
</script>
执行结果: