当前位置: 首页 > Web前端 > HTML

使用Promises时的5个常见错误,你有几个!

时间:2023-03-29 12:12:01 HTML

作者:RaviduPerera译者:前端小智来源:medium微信搜索【大招走向世界】,第一时间与大家分享前端行业动态、学习路径等。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。Promises提供了一种优雅的方式来处理JS中的异步操作。这也是避免“回调地狱”的一种解决方案。但是,没有多少开发人员了解其中的内容。因此,很多人在实践中容易犯错误。在这篇文章中,我将介绍使用Promise时常见的五个错误,希望你能避免这些错误。1.避免Promise地狱通常,Promises用于避免回调地狱。但是滥用它们也会导致Promise成为地狱。userLogin('user').then(function(user){getArticle(user).then(function(articles){showArticle(articles).then(function(){//Yourcodegoeshere...});});});在上面的示例中,我们嵌套了userLogin、getararticle和showararticle三个promise。这样,复杂性将与代码行成比例地增长,并且可能变得不可读。为了避免这种情况,我们需要取消嵌套代码,从第一个then返回getArticle,然后在第二个then处理它。userLogin('user').then(getArticle).then(showArticle).then(function(){//Yourcodegoeshere...});2.在Promise中使用try/catch块通常,我们使用try/catch块来处理错误。但是,不建议将try/catch与Promise对象一起使用。这是因为如果有任何错误,Promise对象会在catch中自动处理它。ewPromise((resolve,reject)=>{try{constdata=doThis();//做一些事情resolve();}catch(e){reject(e);}}).then(data=>console.日志(数据)).catch(错误=>控制台。日志(错误));在上面的示例中,我们在Promise中使用了try/catch块。但是,Promise本身可以捕获其范围内的所有错误(甚至拼写错误),而无需try/catch块。它确保捕获执行期间抛出的任何异常并将其转换为被拒绝的Promise。newPromise((resolve,reject)=>{constdata=doThis();//dosomethingresolve()}).then(data=>console.log(data)).catch(error=>console.log(错误));注意:在Promise块中使用.catch()块至关重要。否则,您的测试用例可能会失败并且应用程序可能会在生产中崩溃。3.在Promise块中使用异步函数Async/Await是一种更高级的语法,用于在同步代码中处理多个Promise。当我们在返回Promise的函数声明之前使用async关键字时,我们可以使用await关键字来停止代码,直到我们正在等待的Promise解决或拒绝。但是,当您将Async函数放在Promise块中时,会产生一些副作用。假设我们想在Promise块内做一个异步操作,所以我们使用async关键字,但不幸的是,我们的代码抛出了一个错误。这样,即使使用catch()块或在try/catch块中等待您的Promise,我们也无法立即处理错误。请看下面的例子。//这段代码无法处理错误newPromise(async()=>{thrownewError('message');}).catch(e=>console.log(e.message));(async()=>{try{awaitnewPromise(async()=>{thrownewError('message');});}catch(e){console.log(e.message);}})();当我在Promise块中遇到async函数时,我尝试将异步逻辑保持在Promise块之外以使其保持同步。10次中有9次有效。但是,在某些情况下,可能需要异步功能。在这种情况下,别无选择,只能使用try/catch块手动管理它。newPromise(async(resolve,reject)=>{try{thrownewError('message');}catch(error){reject(error);}}).catch(e=>console.log(e.message));//usingasync/await(async()=>{try{awaitnewPromise(async(resolve,reject)=>{try{thrownewError('message');}catch(error){reject(错误);}});}catch(e){console.log(e.message);}})();4.创建Promise后立即执行Promise块至于下面的代码片段,如果我们把代码片段放在调用HTTP请求的地方,它会立即执行。constmyPromise=newPromise(resolve=>{//生成HTTP请求的代码resolve(result);});原因是此代码包装在Promise构造函数中。但是,可能有人会认为是myPromise的then方法执行后才触发的。然而,事实并非如此。相反,当创建Promise时,会立即执行回调。这意味着在建立myPromise之后到达以下行时,HTTP请求可能已经在运行,或者至少已安排好。承诺总是急切地执行。但是,如果您希望Promise稍后执行怎么办?如果您现在不想发出HTTP请求怎么办?Promises中是否有某种神奇的机制可以让我们做到这一点?答案是使用函数。函数是一个耗时的机制。它们只会在开发人员用()显式调用它们时执行。简单地定义一个函数并不能给我们带来太多好处。因此,让Promise变得惰性的最有效方法是将其包装在一个函数中!constcreateMyPromise=()=>newPromise(resolve=>{//HTTP请求resolve(result);});对于HTTP请求,Promise构造函数和回调函数只会在函数完成时被调用。所以现在我们有了一个懒惰的Promise,它只会在我们需要的时候实现。5.不一定要使用Promise.all()方法如果你已经工作多年,你已经知道我在说什么。如果有很多互不相关的承诺,我们可以同时解决它们。Promise是并发的,但是如果一个一个的等待,会花费太多的时间,Promise.all()可以节省很多时间。请记住,Promise.all()是我们的朋友const{promisify}=require('util');constsleep=promisify(setTimeout);asyncfunctionf1(){awaitsleep(1000);}asyncfunctionf2(){awaitsleep(2000);}asyncfunctionf3(){awaitsleep(3000);}(async()=>{console.time('sequential');awaitf1();awaitf2();awaitf3();console.timeEnd('sequential');})();上述代码的执行时间约为6秒。但是如果我们用Promise.all()替换它,它会减少执行时间。(async()=>{console.time('concurrent');awaitPromise.all([f1(),f2(),f3()]);console.timeEnd('concurrent');})();总结在本文中,我们讨论了使用Promises时常犯的五个错误。然而,可能有许多简单的问题需要仔细解决。如果大家有更多相关错误,欢迎留言一起讨论。~最后,我是碗志、李志等,退休后想回家摆地摊。下次见!代码部署后可能存在的bug,无法实时获知。事后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的bug监控工具Fundebug。原文:https://blog.bitsrc.io/5-comm...交流有梦想,有干货,微信搜索【大招天下】关注这位还在早期洗碗的洗碗智慧早晨。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。