You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constpromise=newPromise((resolve,reject)=>{// Note: only 1 param allowedreturnresolve(27)})// Parameter passed resolve would be the arguments passed into then.promise.then(number=>console.log(number))// 27
constpromise=newPromise((resolve,reject)=>{// Note: only 1 param allowedreturnreject('💩💩💩')})// Parameter passed into reject would be the arguments passed into catch.promise.catch(err=>console.log(err))// 💩💩💩
你能看出resolve和reject都是回调函数吗?😉
让我们练习一下,尝试构建jeffBuysCake promise。
首先,你知道Jeff说他会买一个蛋糕。那就是一个承诺。所以,我们从空promise入手:
constjeffBuysCake=cakeType=>{returnnewPromise((resolve,reject)=>{// Do something here})}
// A little bit of NodeJS here. This is how you'll get data from the frontend through your API.app.post('/buy-thing',(req,res)=>{constcustomer=req.body// Charge customer here})
// Callback based codeapp.post('/buy-thing',(req,res)=>{constcustomer=req.body// First operation: charge the customerchargeCustomer(customer,(err,charge)=>{if(err)throwerr// Add to database here})})
// Promised based codeapp.post('/buy-thing',(req,res)=>{constcustomer=req.body// First operation: charge the customerchargeCustomer(customer).then(/* Add to database */).catch(err=>console.log(err))})
// Callback based codeapp.post('/buy-thing',(req,res)=>{constcustomer=req.bodychargeCustomer(customer,(err,charge)=>{if(err)throwerr// Second operation: Add to databaseaddToDatabase(customer,(err,document)=>{if(err)throwerr// Send email here})})})
// Promised based codeapp.post('/buy-thing',(req,res)=>{constcustomer=req.bodychargeCustomer(customer)// Second operation: Add to database.then(_=>addToDatabase(customer)).then(/* Send email */).catch(err=>console.log(err))})
你有没有在JavaScript中遇到过
promises
并想知道它们是什么?它们为什么会被称为promises
呢?它们是否和你以任何方式对另一个人做出的承诺有关呢?此外,你为什么要使用
promises
呢?与传统的JavaScript操作回调(callbacks)相比,它们有什么好处呢?在本文中,你将学习有关JavaScript中
promises
的所有内容。你将明白它们是什么,怎么去使用它们,以及为什么它们比回调更受欢迎。所以,promise是什么?
promise是一个将来会返回值的对象。由于这种
未来
的东西,Promises非常适合异步JavaScript操作。通过类比会更好地解析JavaScript
promise
的概念,所以我们来这样做(类比),使其概念更加清晰。想象一下,你准备下周为你的侄女举办生日派对。当你谈到派对时,你的朋友,Jeff,提出他可以提供帮助。你很高心,让他买一个黑森林(风格的)生日蛋糕。Jeff说可以。
在这里,Jeff告诉你他会给你买一个黑森林生日蛋糕。这是约定好的。在JavaScript中,
promise
的工作方式和现实生活中的承诺一样。可以使用以下方式编写JavaScript版本的场景:现在,Jeff尚未采取行动。在JavaScript中,我们说承诺(promise)正在
等待中(pending)
。如果你console.log
一个promise
对象,就可以验证这点。在与Jeff交谈之后,你开始计划下一步。你意识到如果Jeff信守诺言,并在聚会时买来一个黑森林蛋糕,你就可以按照计划继续派对了。
如果Jeff确实买来了蛋糕,在JavaScript中,我们说这个promise是
实现(resolved)
了。当一个承诺得到实现时,你会在.then
调用中做下一件事情:如果Jeff没给你买来蛋糕,你必须自己去面包店买了。(该死的,Jeff!)。如果发生这种情况,我们会说承诺被
拒绝(rejected)
了。当承诺被拒绝了,你可以在
.catch
调用中执行应急计划。我的朋友,这就是对
Promise
的剖析了。在JavaScript中,我们通常使用
promises
来获取或修改一条信息。当promise
得到解决时,我们会对返回的数据执行某些操作。当promise
拒绝时,我们处理错误:现在,你知道一个
promise
如何运作了。让我们进一步深入研究如何构建一个promise
。构建一个promise
你可以使用
new Promise
来创建一个promise。这个Promise构造函数是一个包含两个参数 --resolve
和reject
的函数。如果
resolve
被调用,promise成功并继续进入then
链式(操作)。你传递给resolve
的参数将是接下来then
调用中的参数:如果
reject
被调用,promise失败并继续进入catch
链式(操作)。同样地,你传递给reject
的参数将是catch
调用中的参数:让我们练习一下,尝试构建
jeffBuysCake
promise。首先,你知道Jeff说他会买一个蛋糕。那就是一个承诺。所以,我们从空promise入手:
接下来,Jeff说他将在一周内购买蛋糕。让我们使用
setTimeout
函数模拟这个等待七天的时间。我们将等待一秒,而不是七天:如果Jeff在一秒之后买了个黑森林蛋糕,我们就会返回promise,然后将黑森林蛋糕传递给
then
。如果Jeff买了另一种类型的蛋糕,我们拒接这个promise,并且说
no cake
,这会导致promise进入catch
调用。让我们来测试下这个promise。当你在下面的
console.log
记录时,你会看到promise正在pedding(等待)
。(如果你立即检查控制台,状态将只是暂时挂起状态。如果你需要更多时间检查控制台,请随时将超时时间延长至10秒)。如果你在promise链式中添加
then
和catch
,你会看到black forest cake!
或no cake 😢
信息,这取决于你传入jeffBuysCake
的蛋糕类型。创建一个promise不是很难,是吧?😉
既然你知道什么是promise,如何制作一个promise以及如何使用promise。那么,我们来回答下一个问题 -- 在异步JavaScript中为什么要使用promise而不是回调呢?
Promises vs Callbacks
开发人员更喜欢promises而不是callbacks有三个原因:
为了看到这三个好处,让我们编写一些JavaScript代码,它们通过
callbacks
和promises
来做一些异步事情。对于这个过程,假设你正在运营一个在线商店。你需要在客户购买东西时向他收费,然后将他们的信息输入到你的数据库中。最后,你将向他们发送电子邮件:
让我们一步一步地解决。首先,你需要一种从前端到后端获取信息的方法。通常,你会对这些操作使用
post
请求。如果你使用
Express
或Node
,则初始化代码可能如下所示。如果你不知道任何Node
或Express
(的知识点),请不要担心。它们不是本文的主要部分。跟着下面来走:让我们先介绍一下基于
callback
的代码。在这里,你想要向客户收费。如果收费成功,则将其信息添加到数据库中。如果收费失败,则会抛出错误,因此你的服务器可以处理错误。代码如下所示:
现在,让我们切换到基于
promise
的代码。同样地,你向客户收费。如果收费成功,则通过调用then
将其信息添加到数据库中。如果收费失败,你将在catch
调用中自动处理:继续,你可以在收费成功后将你的客户信息添加到数据库中。如果数据库操作成功,则会向客户发送电子邮件。否则,你会抛出一个错误。
考虑到这些步骤,基于
callback
的代码如下:对于基于
promise
的代码,如果数据库操作成功,则在下一个then
调用时发送电子邮件。如果数据库操作失败,则会在最终的catch
语句中自动处理错误:继续最后一步,在数据库操作成功时向客户发送电子邮件。如果成功发送此电子邮件,则会有成功消息通知到你的前端。否则,你抛出一个错误:
以下是基于
callback
的代码:然后,以下基于
promise
的代码:看看为什么使用
promises
而不是callbacks
编写异步代码要容易得多?你从回调地狱(callback hell)一下子切换到了链式乐土上😂。一次触发多个promises
promises
比callbacks
的另一个好处是,如果操作不依赖于彼此,则可以同时触发两个(或多个)promises,但是执行第三个操作需要两个结果。为此,你使用
Promise.all
方法,然后传入一组你想要等待的promises。then
的参数将会是一个数组,其包含你promises返回的结果。最后,我们来谈谈浏览器支持情况!如果你不能在生产环境中使用它,那为什么要学习
promises
呢。是吧?浏览器支持Promise
令人兴奋的消息是:所有主流浏览器都支持promises!
如果你需要支持
IE 11
及其以下版本,你可以使用Taylor Hakes制作的Promise Polyfill。它支持IE8的promises。😮结语
你在本文中学到了所有关于
promises
的知识。简而言之,promises
棒极了。它可以帮助你编写异步代码,而无需进入回调地狱。尽管你可能希望无论什么时候都使用
promises
,但有些情况callbacks
也是有意义的。不要忘记了callbacks
啊😉。如果你有疑问,请随时在下面发表评论,我会尽快回复你的。【PS:本文译文,若需作者解答疑问,请移步原作者文章下评论】
感谢阅读。这篇文章是否帮助到你?如果有,我希望你考虑分享它。你可能会帮助到其他人。非常感谢!
后话
The text was updated successfully, but these errors were encountered: