一、我们常用的 axios 就是基于 promise 封装的
resolve reject peeding 三个常用请求状态 分别表示成功、失败、等待
promise.all([])、promise.race([]) 两个常用实例方法,分别表示按传入的数组顺序一次执行多个异步请求、按实际代码运行速度一次执行多个异步请求。
const promise1 = request(url, params1, "POST");
const promise2 = request(url, params2, "POST");
const promise3 = request(url, params3, "POST");
// request方法是自己封装的 axios 请求
Promise.all([promise1, promise2, promise3]).then((response=>{
console.log(responses)
}))
另外,promise 还可以链式调用,执行顺序和 promise.all([]) 一样。
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000); // (*)
}).then(function(result) { // (**)
alert(result); // 1
return result * 2;
}).then(function(result) { // (***)
alert(result); // 2
return result * 2;
}).then(function(result) {
alert(result); // 4
return result * 2;
});
案例1:基于 promise 封装的方法
function loadScript(src) {
return new Promise(function(resolve, reject) {
let script = document.createElement('script');
script.src = src;
script.onload = () => resolve(script);
script.onerror = () => reject(new Error(`Script load error for ${src}`));
document.head.append(script);
});
}
用法:
let promise = loadScript("http://www.baidu.com");
promise.then(res => alert(`${res.src} is loaded!`),error => alert(`Error: ${error.message}`)); //resolve 和 reject
或者:
promise.then(res => alert('Another handler...')); //只有 resolve
promise.catch(err => alert(err)) //捕获异常
案例2:发生ajax 请求
<body>
<div class="container">
<h2 class="page-header">Promise 封装 AJAX 操作</h2>
<button class="btn btn-primary" id="btn">点击发送 AJAX</button>
</div>
<script>
//接口地址 https://api.apiopen.top/getJoke
//获取元素对象
const btn = document.querySelector('#btn');
btn.addEventListener('click', function(){
//创建 Promise
const p = new Promise((resolve, reject) => {
//1.创建对象
const xhr = new XMLHttpRequest();
//2. 初始化
xhr.open('GET', 'https://api.apiopen.top/getJoke');
//3. 发送
xhr.send();
//4. 处理响应结果
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
//判断响应状态码 2xx
if(xhr.status >= 200 && xhr.status < 300){
//控制台输出响应体
resolve(xhr.response);
}else{
//控制台输出响应状态码
reject(xhr.status);
}
}
}
});
//调用then方法
p.then(value=>{
console.log(value);
}, reason=>{
console.warn(reason);
});
});
</script>
</body>
案例三:封装基于axios的文件上传接口请求
import axios from 'axios';
function upload(url, formdata) {
let promise;
return new Promise((resolve, reject) => {
promise = Axios.post(url, formdata);
promise.then((response) => {
resolve(response.data);
}).catch(error => {
reject(error);
})
})
}
var globalUrl = "http://192.168.5.132:8080/"; // 地址可以改成自己项目中的地址
// 接口列表,供其它页面调用使用,如还有其它上传接口,可复制一份改下接口地址根函数名就行
export const uploadFile = (formdata) => upload(globalUrl + 'oa/fileInfo/uploadFile', formdata);
其它页面调用使用:
// 引入调用接口
import { uploadFile } from '../../api/fileupload';
let params = new FormData(); //创建form对象
params.append("file", file.file);
// 直接传入参数
uploadFile(params)
.then(res => {
// 后台返回的状态码,自行根据后台的要求进行修改
if (res.code == 200) {
console.log(res);
}
});
补充:Promise中的then第二个回调参数和catch有什么区别?
- 第一:reject是用来抛出异常的,catch是用来处理异常的;
- 第二:reject是Promise的方法,而then和catch是Promise实例的方法(Promise.prototype.then
和 Promise.prototype.catch) 主要区别就是,如果在 then
的第一个回调函数里抛出了错误,后面的catch能捕获到,而then的第二个回调函数捕获不到
二、async/await
Async/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用
在一个函数前加上“async” 这个单词 就表示这个函数总是返回一个 promise,所以说,async 确保了函数返回一个 promise,也会将非 promise 的值包装进去
关键字 await 让 JavaScript 引擎等待直到 promise 完成并返回结果。
async/await 和 promise.then/catch
- 当我们使用 async/await 时,几乎就不会用到 .then 了,因为 await 为我们处理了等待。
并且我们使用常规的 try…catch 捕获异常 而不是 .catch。这通常更加方便
案例:让我们改写上面的 loadScript
function loadScript(src) {
return new Promise(function(resolve, reject) {
let script = document.createElement('script');
script.src = src;
script.onload = () => resolve(script);
document.head.append(script);
});
}
async function test(){
try{
//把await及获取它的值的操作放在try里
let res = await loadScript('http://www.baidu.com')
console.log('成功' + n)
}catch(error){
//失败的操作放在catch里
console.log('异常' + error)
}
}
test()
另外:loadScript 异步方法还可以换成 axios 请求
async getAssetTypeTree(id) {
try {
const res = await this.$http.requestApi('getAssetTypeTree', {
id: id
})
const idx = this.list.findIndex(item => item.id === id)
this.list[idx].children = res.data || []
} catch (error) {
const idx = this.list.findIndex(item => item.id === id)
this.list[idx].children = []
}
},
参考:
https://zh.javascript.info/async-await
https://www.jianshu.com/p/b4fd76c61dc9
https://www.jianshu.com/p/7e60fc1be1b2