目录
2、promise对象用于表示异步操作的最终完成或失败,及其结果值。
4、finally 无论resolve, 还是reject 都会执行
5、因为 then 会返回一个新的Promise,所以可以链式调用。
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返回:
- 所有promise的resolve都结束
- 没有promise了
reject返回:
- 任何一个promise的reject执行,就返回
- 输入不合法的promise
- 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 文本。