Promise:es6新增对象
作用:更优雅的处理异步任务结果,对异步任务进行封装。
回调函数处理异步任务结果( ajax,setTimeout )
使用:
创建对象:let promise =new Promise( function(resolve,reject){
//resolve处理异步任务成功的结果 resolve(成功的数据‘’)
//reject 处理异步任务失败的结果 reject(‘失败的数据’)
//异步任务封装
setTimeout(function){
if(true){
resolve('成功’)}
else(){
reject(‘失败')
} }
},1000)
pormise.then(function(result){
result=>成功
})
promise.catch(function(error){
error=>失败
})
使用:
let promise = new Promise((resolve, reject) => {
let num = Math.floor(Math.random() * 10) // [0-10)
console.log('num ', num)
// 封装异步任务
setTimeout(() => {
if (num % 2 == 0) {
resolve('成功')
} else {
reject('失败')
}
}, 1000)
console.log('promise封装代码执行完成')
})
promise.then(result => {
console.log('then 接收成功数据 ', result)
})
promise.catch(error => {
console.log('catch 接收失败数据 ', error)
})
Promise链式调用:
比回调函数更好更优雅的处理异步结果
若有多个请求,后面请求需要用到前面请求的结果
A -----> B(a) -------->C(b)
a b c
使用回调函数/嵌套,会出现回调地狱
ajax({
method:'get',
url:'A请求地址',
success:function(a){
ajax({
method:'get',
url:'B请求地址',
data:{a} //A请求返回结果作用参数
success:function(b){
ajax({
method:'get',
url:'C请求地址',
data:{a} //A请求返回结果作用参数
success:function(c){
ajax({
method:'get',
url:'D请求地址',
data:{a} //A请求返回结果作用参数
success:function(c){
}
})
}
})
}
})
}
})
解决这个问题,使用 Promise链式调用
promiseA.then(a=>{
let promiseB = new Promise((resolve,reject)=>{
//封装B异步操作 a
})
return promiseB
}).then(b=>{
let promiseC = new Promise((resolve,reject)=>{
//封装C异步操作 b
})
return promiseC
}).then(c=>{
console.log(c)
})
链式调用示例:
<script src="./myajax.js"></script>
<script>
/*
封装一个函数获取promsie对象, promise对象封装处理网络请求异步任务
options = {
method:'get',
url:''
data:{}
}
*/
myPromise({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/list',
})
.then(result => {
let list = result.resultInfo.list //商品列表
return myPromise({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/find',
data: {
id: list[0].id,
},
})
})
.then(resultB => {
console.log(resultB)
// return myPromise({
// method:'get',
// url:'C'
// })
})
</script>
引用的myajax是我们之前总结过的,在此的基础上,加上promise
/**
* 封装一个函数获取promsie对象, promise对象封装处理网络请求异步任务
options = {
method:'get',
url:''
data:{}
}
* @param {*} options
* @returns
*/
function myPromise(options) {
return new Promise((resolve, reject) => {
ajax({
method: options.method,
url: options.url,
data: options.data,
success: function (result) {
resolve(result)
},
fail:function(error){
reject(error)
}
})
})
}
/**
let options = {
method: 'get',
url: '',
data:{
username:'jack'
age:18
},
success:function(data){
}
}
*/
function ajax(options) {
// 1. 创建XMLHttpRequest
let xhr = new XMLHttpRequest()
let param = formateParam(options.data) // name=jack&age=18
let method = options.method.toUpperCase()
// 2. 建立连接
if (method == 'GET') {
xhr.open(options.method, options.url + '?' + param)
// 3. 发送请求
xhr.send()
}else if(method == 'POST'){
xhr.open(options.method,options.url)
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
xhr.send(param)
}
// 4. 接收响应数据
xhr.onreadystatechange = function () {
// 4.1 是否响应完成
if (xhr.readyState === 4) {
// 4.2 是否成功响应
if (xhr.status === 200) {
let data = xhr.responseText // 响应内容
data = JSON.parse(data)
options.success(data)
} else {
// alert('网络出错 ' + xhr.status)
options.fail('网络出错 ' + xhr.status)
}
}
}
}
/**
* 格式化参数
* {name:'jack',age:18} => name=jack&age=18
* 遍历对象,属性转换成名称=值形式,存储到数组, 再将数组元素用&符号拼接join('&)
* ['name=jack','age=18'] ->
*/
function formateParam(obj) {
let arr = []
for (const key in obj) {
let item = `${key}=${obj[key]}` // name=jack age=18
arr.push(item) // ['name=jack','age=18;]
}
return arr.join('&') // name=jack&age=18
}
// let str = formateParam({name:'jack',age:18})
// console.log(str)
那么迄今为止,我们一共学习了三种方式:
写项目
调用接口获取后端数据
1. 原生ajax
let xhr = new XMLHttpRequest()
xhr.open()
xhr.send()
xhr.onreadystatechange=function(){
}
2. 封装ajax回调函数
引入myajax.js
ajax({
method:'get',
url:'',
data:{},
success:function(res){},
fail:function(error){}
})
3. 封装promise写法
引入myajax.js
myPromise({
method:'get',
url:'',
data:{}
}).then(res=>{
成功
}).catch(error=>{
失败
})