无论是在开发中还是在面试中 promise 都是一个非常重要的内容。常见的面试中都会问及到 promise.then()、Promise.all 或者配合 async/await 使用的方式。
但是,一旦我们遇到更高级别的岗位(比如大厂高P岗位),那么以上这些知识可能就不够使用了。所以说,咱们今天就来分享 5个promise的“高级”使用技巧,提高对 promise 的理解,帮大家通过高P面试!
当面对必须顺序执行一系列任务的场景时,我们第一时间都会想到 “await”。但是除了 await 之外,使用 Promise 的替代方法可能更加优雅。
const requestAry = [() => api.request1(), () => api.request2(), () => api.request3()];// 使用 `await`for (const requestItem of requestAry) { await requestItem();}// 使用promise进行串行执行const finallyPromise = requestAry.reduce( (currentPromise, nextRequest) => currentPromise.then(() => nextRequest()), Promise.resolve() );
该方法使用“then”函数,可以简洁高效地连接 Promise,确保任务的串行执行。
使用 async/await 作为接收异步函数返回值的这种方式大家应该都比较熟悉,但很少有人认识到异步函数从根本上来说是返回一个 promise。
我们来看下面这个场景
const fn1 = async () => 1;const fn2 = () => Promise.resolve(1);fn1(); // 返回值为1的promise对象
通常,await 与 Promise 对象一起使用,等待 promise 被解析。 因此,等待 fn1 函数也相当于以下内容:
await fn1();-----const promiseInst = fn1();await promiseInst;
但是,对于 await 大家需要知道:当后面的值不是 Promise 对象时,它将会把该值包装在 Promise 对象中。 因此,await之后的代码必须异步执行:
Promise.resolve().then(() => { console.log(1);});await 2;console.log(2);// 输出: 1 2
这相当于:
Promise.resolve().then(() => { console.log(1);});Promise.resolve().then(() => { console.log(2);});
当先前的请求仍处于 待处理状态 时发送重复的请求可能会导致不必要的资源消耗。
request('GET', '/test-api').then(response1 => { // …});request('GET', '/test-api').then(response2 => { // …});
并且这种场景非常常见:
所以,我们可以对 promise 进行对应的封装处理,利用 缓存策略 解决这个问题,可以参考以下代码:
// 缓存对象const pendingPromises = {};function request(type, url, data) { const requestKey = JSON.stringify([type, url, data]); // 读取缓存 if (pendingPromises[requestKey]) { return pendingPromises[requestKey]; } const fetchPromise = fetch(url, { method: type, data: JSON.stringify(data) }) .then(response => response.json()) .finally(() => { delete pendingPromises[requestKey]; }); // 存入缓存 return pendingPromises[requestKey] = fetchPromise;}
我们知道 promise 拥有三种状态的返回值:
// 返回新的 Promise(resolve => resolve(1))Promise.resolve().then(() => 1); // 返回新的 Promise(resolve => resolve(Promise.resolve(2)))Promise.resolve().then(() => Promise.resolve(2)); // 返回新的 Promise(resolve => resolve(Promise.reject(new Error('abc'))))Promise.resolve().then(() => { throw new Error('abc') }); // 返回新的 Promise(resolve => resolve(2))Promise.reject().then(() => 1, () => 2);
// 返回新的 Promise(resolve => resolve(3))Promise.reject().catch(() => 3); // 返回新的 Promise(resolve => resolve(promise object calling catch))Promise.resolve().catch(() => 4);
// 返回 Promise.resolve()Promise.resolve().finally(() => {}); // 返回 Promise.reject()Promise.reject().finally(() => {});
// 返回处于 pending 状态下的 Promise, 1秒后 resolve 为 5。Promise.resolve(5).finally(() => new Promise(res => { setTimeout(res, 1000);})); Promise.reject(6).finally(() => new Promise(res => { setTimeout(res, 1000);})); // 返回处于 pending 状态下的 Promise, 在1秒后 reject 为 6。
promise 有两种处理错误的方式,分别是:
当请求出现错误时,第二个回调函数和 Promise 的 .catch 都会被触发。
乍一看,它们好像没什么区别,但是——前者(第二个参数回调函数)无法捕获“then”当前第一个回调函数中抛出的错误,而“catch”可以:
Promise.resolve().then( () => { throw new Error('成功的回调出现错误'); }, () => { // 这里不会执行 }).catch(reason => { console.log(reason.message); // 成功的回调出现错误});
本文链接:http://www.28at.com/showinfo-26-82357-0.html你必须要知道的,五个Promise高级使用技巧
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com