本文跟大家分享5个应用 promise 时的普遍不正确,给大家迅速防坑,希望能帮助到大家!
Promise 提供了一种雅致的方法去解决 JS 里的异步操作。那也是防止“回调地狱”解决方案。但是,并没有太多开发者掌握在其中内容。因而,很多人结合实际通常会做错事。【相关信息:javascript学习教程】
在本文中,介绍一下应用 promise 时的五个普遍不正确,希望大家可以防止这种不正确。
1.防止 Promise 炼狱
一般,Promise就是用来防止回调地狱。但乱用他们也会造成 Promise是炼狱。
userLogin('user').then(function(user){
getArticle(user).then(function(articles){
showArticle(articles).then(function(){
//Your code goes here...
});
});
});
在后面的例子中,对于 userLogin
、getararticle
和 showararticle
嵌入了三个promise。那样多元性将按照编码行占比提高,如果它越来越不能读。
为了防止这样的事情,我们应该消除代码的嵌入,从第一个 then
中回到 getArticle
,之后在第二个 then
中正确处理它。
userLogin('user')
.then(getArticle)
.then(showArticle)
.then(function(){
//Your code goes here...
});
2. 在 Promise 中应用 try/catch
块
一般来说,我们使用 try/catch
块来处理错误。但是,不推荐在 Promise
目标中应用try/catch
。
主要是因为假如出现任何不正确,Promise目标会到 catch
内全自动解决。
ew Promise((resolve, reject) => {
try {
const data = doThis();
// do something
resolve();
} catch (e) {
reject(e);
}
})
.then(data => console.log(data))
.catch(error => console.log(error));
在后面的例子中,大家在Promise 内用了 try/catch
块。
可是,Promise本身会则在修饰符内捕获每一个不正确(甚至电脑打字不正确),而无需 try/catch
块。它保证在实施过程中抛出的全部出现异常都已经被获得并转换成被抗拒的 Promise。
new Promise((resolve, reject) => {
const data = doThis();
// do something
resolve()
})
.then(data => console.log(data))
.catch(error => console.log(error));
留意:在 Promise 块中应用 .catch()
块是十分重要的。不然,你测试案例可能不成功,并且应用软件在制造环节可能奔溃。
3. 在 Promise 块内应用异步函数
Async/Await
是一种更高级的词法,用以解决同歩编码里的好几个Promise。我们在一个函数声明前应用 async
关键词时,他会回到一个 Promise,我们可以使用 await
关键词来终止编码,直至大家正在等待的Promise处理或回绝。
可是,如果你把一个 Async 函数公式放在一个 Promise 块里边时,会有一些不良反应。
假定大家想要在Promise 块里做一个异步操作,所以使用了 async
关键词,但,不巧合的是我们自己的编码提出了一个错误。
那样,即便应用 catch()
块或者在 try/catch
块内等待你的Promise,我们不能马上解决这一不正确。可以看下边的事例。
// 此编码没法处理错误
new Promise(async () => {
throw new Error('message');
}).catch(e => console.log(e.message));
(async () => {
try {
await new Promise(async () => {
throw new Error('message');
});
} catch (e) {
console.log(e.message);
}
})();
当他在Promise块内碰到 async
函数公式时,我试图将 async
逻辑性维持在 Promise 块以外,以保持其趋同性。10次中有9次都能成功。
但是,在某些情况下,可能还需要一个 async
函数公式。在这样的情况下,也没有选择,只能用try/catch
块来手动管理。
new Promise(async (resolve, reject) => {
try {
throw new Error('message');
} catch (error) {
reject(error);
}
}).catch(e => console.log(e.message));
//using async/await
(async () => {
try {
await new Promise(async (resolve, reject) => {
try {
throw new Error('message');
} catch (error) {
reject(error);
}
});
} catch (e) {
console.log(e.message);
}
})();
4.在创建 Promise 后立即执行 Promise 块
对于下边的代码片段,假如我们把编码片段放到启用HTTP请求的地区,它就会被立即执行。
const myPromise = new Promise(resolve => {
// code to make HTTP request
resolve(result);
});
主要原因是这一段编码被裹在一个Promise对象中。但是,有的人可能会认为仅有在实施myPromise
的then
方式之后才被开启。
但是,实情并不是这样。反过来,当一个Promise被建立时,调整被立即执行。
这就意味着在建立 myPromise
以后抵达下边一行时,HTTP要求很有可能早已在运行,或者至少处在生产调度情况。
Promises 一直急切执行过程。
可是,假如愿以后再执行 Promises,该怎么做?如果你现在不愿传出HTTP要求怎么处理?是否存在什么神奇的制度内放置 Promises 中,使我们可以做到这一点?
关键就是使用函数。函数是一种用时的制度。只有在开发人员确切地用 ()
来启用他们时,他们才能实行。简单的界定一个函数没法使我们收获什么。因此,让 Promise 越来越懒散最有效途径是把其裹在一个函数中!
const createMyPromise = () => new Promise(resolve => {
// HTTP request
resolve(result);
});
针对HTTP要求,Promise 对象和调用函数只会在函数公式强制执行的时候才会被启用。所以目前我们有一个懒散的Promise,只会在我们应该的时候才能实行。
5. 不一定应用 Promise.all() 方式
如果已经工作多年,应当已知道我在说什么了。若是有很多彼此之间不相关的 Promise,我们能与此同时解决他们。
Promise 是高并发的,但假如你一个一个地等候他们,会太耗时间,Promise.all()
能节省大量时间。
记牢,Promise.all() 是我们的好朋友
const { promisify } = require('util');
const sleep = promisify(setTimeout);
async function f1() {
await sleep(1000);
}
async function f2() {
await sleep(2000);
}
async function f3() {
await sleep(3000);
}
(async () => {
console.time('sequential');
await f1();
await f2();
await f3();
console.timeEnd('sequential');
})();
以上代码的实施时间大约为 6
秒。但如果我们用 Promise.all()
取代它,将减少实施时间。
(async () => {
console.time('concurrent');
await Promise.all([f1(), f2(), f3()]);
console.timeEnd('concurrent');
})();
汇总
在这篇文章中,大家探讨了应用 Promise 常常犯的五个不正确。但是,很有可能还有一些简单的题必须细心处理。
假如你还有很多有关错误,欢迎在评论区留言一起讨论。
英文原文详细地址:https://blog.bitsrc.io/5-common-mistakes-in-using-promises-bfcc4d62657f
创作者:Ravidu Perera
大量程序编写基本知识,请访问:编程学习!!
以上就是关于迅速防坑,聊一聊5个用promise最常见的不正确!的具体内容,大量欢迎关注AdminJS其他类似文章!