一篇傻瓜都能看懂的Promises文章

JavaScript Promises 其实不难。然而,很多人一开始就觉得有点难理解.。因此我想用一种假设的方式写下我理解 promise。

(一)理解 promises

举个简单例子:

想象你是一个孩子。你老妈承诺下礼拜 给你买个新手机。你 [不知道] 你是否会得到手机直到下礼拜。你老妈可以真的买你一个全新的手机,也可以让你滚蛋并告诉你不买了(如果她不高兴了)。

这是一个承诺。一个承诺有 3 个状态。分别是:

1.悬而未决:你 [不知道] 你是否会得到手机直到下礼拜。

2.解决:你老妈可以真的买你一个全新的手机。

3.拒绝:你老妈拒绝给你买,因为你惹她不高兴。

(二)创建一个 promise

咱们把上面的例子转换成 JavaScript.

–> 代码表现力挺强的嘛!

  1. “isMomHappy”是个布尔值,定义老妈是否开心。
  2. “willIGetNewPhone”是一个 promise,这个承诺可以解决(给你买),也可以拒绝(老妈不开心就不给你买)。.
  3. 还有一个标准语法去定义一个新的 promise,参考MDN documentation,看下面代码:

  1. 需要记住的是,在你定义的 promise 里,当结果是成功的,叫 解决(你的成功值),如果结果失败了,叫 拒绝(你的失败值)。
  2. 在我们的例子中,如果老妈高兴,我们会得到一个电话。因此,我们称 resolvefunction(电话变量)。如果老妈不高兴,我们称为 拒绝函数(拒绝的理由);

(三)玩转 promises

现在有了 promise,咱们就开始玩一玩。

  1. 我们有一个函数“askmom”。在这个函数中,我们将使用我们的承诺“ willigetnewphone”。
  2. 当我们的 promise 是解决或者拒绝的时候,我们要做点事儿,我们用“.then & .catch ”来处理我们的行动;
  3. 在“.then”里面有函数“ function(fulfilled) { … } ”。这个函数的返回值是啥呢?返回值是 promise 解决的值(你的成功时候的值);在我们的案例中它是一部新电话 。
  4. 在 “.catch”里面有函数”function(error){ … } “。猜测一下,其实这个返回的是错误值,就是 promise 拒绝的值。

走一下案例看下结果!

(四)链接 promises

Promises 都是可链的。

这样说吧,你,咱例子中的孩子,承诺给你的朋友说:如果你老妈给你买了新手机,就让你的朋友过过眼瘾,你要显摆显摆!

这又是另外一个 promise 了,写成代码看下!

注意:

  • 在这个例子中,你可能会意识到我们不叫 拒绝。因为它是可选的。
  • 我们可以缩短这个案例,看代码:

咱们现在链接 promise。你,这个孩子只能在得到手机后才能显摆手机。

–> 简单吧!

(五)promises 都是异步的

Promises 都是异步的,咱们在这个 promise 开始和结束前写一段信息。

期望输出的顺序是什么?也许你以为:

然而,实际的输出序列是:

)

为啥?因为生活就是不等人的,JavaScript 也是!

你,孩子,不会说不去玩了就干等你老妈的承诺(新手机),对吧。这就是 异步调用,代码将无阻塞运行或等待结果。任何需要等 promise 的行为放在”.then”里面。

Promise 在 ES5 /ES6 /ES7 下:

ES5 - 大多数的浏览器

ES5 不支持 promise,大多数浏览器借助第三方库(BluebirdQ)的话可以实现;

ES6 - 现代浏览器

演示代码是 ok 的,因为 ES6 支持 promise。此外,我们也可以用 ES6 的箭头函数来简化代码。也可以用上 let 和 const。

下面是 ES6 的演示代码:

–> 注意到所有的 var 都被 const 取代。所有的函数(解决,拒绝) 都使用箭头函数简化。

ES7 - 异步等待使语法看起来更漂亮!

ES7 介绍 异步 和 等待 语法。它使异步语法看起来更漂亮、更容易理解,没有 “.then” 和”.catch”。

用 ES7 语法来重写我们的例子:

  1. 当你需要在一个函数里面返回一个 promise,你在异步 调用这个函数。例如 案例中的异步函数”function showOff(phone)”。
  2. 当你需要一个 promise,你就在等待着 。例如 “let phone = await willIGetNewPhone;” & “ let message = await showOff(phone)”。
  3. 使用 “ try { … } catch(error) { … } “ 捕捉 promise 错误/拒绝 。

为什么使用 promise?什么时候使用它们?

为什么我们需要 promise?promise 之前的世界是怎样的?在回答这些问题之前,让我们回到最基础的地方。

对比正常函数和异步函数

让我们来看看这两个例子,这两个例子执行两个数字相加:

正常函数两个数相加:

异步函数两个数相加:

如果你用正常的函数让两个数字,你会立即得到结果.。但是,当你发出远程调用来得到结果时,你需要等待,你不能立即得到结果.。

或者这样说,你不知道你是否会得到结果,因为服务器可能会下降,响应速度慢等,你不希望在等待结果的时候,整个进程被阻止。调用 API,下载文件,读取文件中的一些你要执行的常用的异步操作。

Promises 之前的世界:Callback 回调

我们必须使用 promise 来实现异步调用吗?不是的,在 promise 之前,我们使用回调。回调函数只是你得到返回结果时调用的函数.。让我们使用回调修改前面的例子。

异步看起来 ok,为啥还要用 promise 呢?

如果你想进行后续的异步操作怎么办?

三个数相加,正常函数这样写:

怎么看起来像回调?

语法对用户是友好的。有一个更好的术语,它看起来像一个金字塔,但人们通常把这称为“回调地狱”,因为回调嵌套到另一个回调。假设你有 10 的回调,你的代码将嵌套的 10 倍!

逃离回调地狱吧!

让 promise 来拯救。让我们来看看同样的例子的 promise 版本。

有了承诺,我们用”.then”扁平化回调。在某种程度上,因为没有回调嵌套,它看起来干净。当然,用 ES7 异步语法,可以让他看起来更简洁!

新家伙:Observables 观测值

在 promise 已经让你很幸福的时候,Observables 这货来锦上添花,让处理异步数据量更容易。

Observables 是懒惰的事件流,可以发出零个或多个事件,而且可能完成也可能不完成。

promise 和 observable 的关键区别是:

  • Observables 观测值是可以取消的
  • Observable 是懒惰的

不要害怕,让我们来看看 Observables 的案例。在这个例子中,关于 Observables 使用 RxJS。

Observables 观测值可以很容易的做一些时髦的东西。看案例:

好吧,咱们以后再接着讨论 Observables 观测值吧!


文章作者: xkloveme
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 xkloveme !
评论
 上一篇
如何更好地运用 Chrome (Google) 如何更好地运用 Chrome (Google)
已经在很多工具类文章前言中,提及使用工具的重要性;以至于在写这篇时候,大为窘迫:穷尽了脑海中那些名句箴言,目测都已然在先前文章中被引用。鉴于杳让人心底意识到工具的重要性,并且能践行之,远比介绍如何使用重要的多,所以,开篇之前,还是得再次重申
2017-09-09
下一篇 
移动端或者pc端不允许点击返回按钮 移动端或者pc端不允许点击返回按钮
公司做移动端,支付成功之后摁返回按钮导致短信再次发送或者接口再次请求,只想让他点击页面指定的返回按钮,但是由于移动端不好监听手机的物理返回键以及微信左上角的返回按钮,经公司大牛研究好久出来下面代码 history.pushState({},
2017-08-30
  目录