Promise 是异步编程的一种更优雅的解决方案,比传统的解决方案——回调函数——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
- 简单理解为:
promise是对异步操作的封装,封装异步文件读写, 封装ajax异步网络请求…
- 使用情况:
有多个请求,后面请求需要用到前面的请求结果
请求;A -> B(a) -> C(b)
参数:a b
如果使用回调函数,就会出现很多嵌套—不推荐
语法
ES6新增一个对象
- 封装异步读取文件promise对象
- 处理异步文件读取成功&失败的结果
/*
使用promise封装定时器异步任务,判断随机数偶数返回'成功'奇数返回'失败'
不使用promise实现,判断随机数偶数返回'成功'奇数返回'失败'
*/
let promise = new Promise((resolve, reject) => {
// resolve 函数 处理异步任务成功的结果 resolve('成功')
// reject 函数 处理异步任务失败的结果 reject('失败')
let num = Math.floor(Math.random() * 10) // [0-10)
console.log('num ', num)
// 1、封装异步任务
setTimeout(() => {
if (num % 2 == 0) {
resolve('成功')
} else {
reject('失败')
}
}, 1000)
console.log('promise封装代码执行完成')
})
// 2、处理异步文件读取成功&失败的结果
promise.then(result => {
console.log('then 接收成功数据 ', result)
})
promise.catch(error => {
console.log('catch 接收失败数据 ', error)
})
- 链式写法:
上述可以不声明,直接return返回promise对象
如:retuen new Promise((resolve,reject)=>{}
作用
对异步任务进行封装,更好的更优雅的处理异步任务结果
解决回调嵌套的问题
回调函数嵌套问题-回调地狱
回调地狱,其实就是回调函数嵌套过多导致的
用Promise封装异步ajax(重)
封装一个Promise函数,再之后需要使用到时,直接传参就行
myajax.js
/**
* 封装一个函数获取promsie对象, promise对象封装处理网络请求异步任务
* 通过向函数里传参完成多次异步任务
myPromise({
method:'get',
url:''
data:{}
})
写在index.js
* @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)
}
})
})
}
index.js
//被调用时:
myPromise({
method:"get",
url:"http://...",
data:{id}
}).then(res=>{
//拿到数据执行操作
showProductList(res.resultInfo.list)
})
//传参
let promise = myPromise({
method:“get | post”,
url:“地址”
})
//拿到数据,执行操作
promise.then(result=>{
let list =
)
//回调函数封装Ajax–不推荐
**//回调函数封装Ajax**--不推荐
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)
}
}
}
}
网络请求获取后端数据时
1、原生ajax
2、ajax封装
3、封装promise myPromise()√√√
4、axios库
实际运用:
//前端的index.js里的以下代码优化
function getProductList(){
ajax({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/list',
success: function (res) {
//拿到回调函数从后端获取的数据
showProductList(res.resultInfo.list)
},
})
}
//替换成Promise封装
function getProductList(){
myPromise({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/list',
}).then(res=>{
//成功后执行的函数
showProductList(res.resultInfo.list)
})
}
Promise对象有以下两个特点
- 对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。
只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。
Promise类对象方法
- Promise.resolve 方法—返回成功结果
let promise1 = myPromise({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/list',
})
let promise2 = myPromise({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/banner',
})
Promise.resolve('成功').then(res=>console.log(res))
- Promise.reject 方法—返回失败结果
let promise1 = myPromise({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/list',
})
let promise2 = myPromise({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/banner',
})
Promise.reject('失败').then(null,error=>console.log(error))
可用于测试:
// 满足条件返回promise对象
function test(){
if(true){
// new Promise(()=>{ })
return Promise.resolve('成功')
}else{
Promise.reject('失败')
}
}
- Promise.race—竞争执行,谁先执行先返回谁
let promise1 = myPromise({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/list',
})
let promise2 = myPromise({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/banner',
})
Promise.race([promise1, promise2]).then(res => console.log(res))
- Promise.all—同时并发执行,返回数组形式结果
let promise1 = myPromise({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/list',
})
let promise2 = myPromise({
method: 'get',
url: 'http://10.7.162.150:8089/api/shop/banner',
})
Promise.all([promise1, promise2]).then(res => console.log(res))
async/await
- async关键字写在函数头部, 表示该函数是一个异步执行的函数
- await关键字表示等待的意思, 只能用在async异步函数中, 后面跟promise对象
=> 等待promise封装的异步操作执行完,返回结果