JavaScript ES6 难点之一就是 Promise,今天做一下相关知识点整理。如果面试,只需要了解这些就够了,多了也用不上。
一、promise 用途,基本的promise与then
1、Promise 是对象
2、promise对象用于表示异步操作的最终完成或失败,及其结果值。
3、then是挂载在 promise 的原型链上的属性。
4、finally 无论resolve, 还是reject 都会执行
Promise.prototype.then(onFulFilled, onRejected)
5、因为 then 会返回一个新的Promise,所以可以链式调用。
基本的Promise.then 使用
const pTest = function () {
let randNum = Math.random();
return new Promise((resolve, reject) => {
setTimeout( () => {
randNum > 0.5 ? resolve(randNum) : reject(randNum);
}, 1000);
});
}
pTest().then(
paramResolve => {
console.log(`this is fulFilled, param is ${paramResolve}`);
},
paramReject => {
console.log(`this is reject, param is ${paramReject}`);
});
二、promise all
1、用于处理多级联调用下,代码语义不明。输入的迭代类型(iterable)是Array,Map,Set。统一处理所有的resolve和reject。
2、返回情况
resolve返回:
1. 所有promise的resolve都结束
2. 没有promise了
reject返回:
1. 任何一个promise的reject执行,就返回
2. 输入不合法的promise
3. reject返回的是第一个reject的信息
3、如何用JS代码实现
function all(iterable) {
return new Promise((resolve, reject) => {
let resolveArr = []; // 所有 promise 的 resolve 参数
for (let key in iterable) {
let item = iterable[key];
// 判断是否为promise
if (typeof item === 'object' && typeof item.then === 'function') {
item.then(
resolveParam => {
resolveArr[key] = resolveParam
// 判断是否所有 resolve 都执行了
if (resolveArr.length === iterable.length) {
resolve(resolveArr);
}
},
// 如果当前item执行reject则整个all结束,返回
reject);
} else {
resolveArr[key] = item;
}
}
});
}
all([
Promise.reject(123), // 1
Promise.resolve(456), // 2
new Promise((resolve, reject) => {
setTimeout(
() => {
resolve(789)
},
5000); // 3
})
]).then( resolveParam => {
console.log(resolveParam);
}).catch( err => {
console.log(err);
})
注释1 处,直接返回 reject,输出 123 结束 注释2 处,如果把1处 注释掉运行,输出 456,789 注释3 处,此处会pending 5秒
三、React 中的 fetch
fetch 比 XmlHttpRequest 效率高。实质也是一个Promise 第一次,header 返回,第二次数据返回。
fetch('/file.txt').then( res => {
console.log('网络成功');
console.log(res);
// let {ok} = res;
// if(ok){
// console.log('接受成功');
// }else{
// console.log('接受失败');
// }
// json()使用json格式解析数据,也是返回Promise
// res.json().then(data => {
// console.log(data);
// }, err => {
// console.log('解析失败');
// });
return res.json(); //res.json 也是一个Promise
}, err => {
console.log('网络失败');
}).then(data => {
console.log(data);
}, err => {
console.log('解析失败');
});
四、async-await
async-await是基于Promise的语法糖,很多高级程序员不习惯JS 的写法,改造出来的这种写法,目的在于只关注resolve,用catch去处理reject
(async () => {
try{
let res = await fetch('/public/exist.txt');
let {ok} = res;
if(ok){
console.log('接受成功');
}else{
console.log('接受失败');
}
// let data = await res.json();
// let data = await res.arrayBuffer();
let data = await res.text();
console.log(data);
}catch(err){
console.log('失败');
}
})();
res能解析哪些格式?
- .json JSON和数组
- .arrayBuffer() 二进制的数组
- .blob 二进制大对象:来源于数据库,不需要解析,用于多媒体文件。
- .text 文本。