这篇文章面向对Promise不甚了解的朋友,我将告诉你如何把它快速运用在开发中。
什么是Promise?
简单几句介绍一下。Promise是抽象异步处理对象以及对其进行各种操作的组件。你可以理解为:它的出现,是为了让我们更方便的进行异步处理。
在Promise出现之前,说到JavaScript的异步处理,我们都会想到回调函数,like this:
|
|
上面遵循Node.js
的规定,回调的第一个参数是error
。如果所有的回调函数都像Node.js
一样,统一参数使用规则的话,那写法会很明了,但也仅仅是编码规范而已,使用不同的写法也不会出错。
而Promise则是把异步处理对象和处理规则进行规范化,并采用统一的接口来编写,使用规定方法之外的写法都会出错。
我们可以先看一个简单的使用Promise进行异步处理的例子:
|
|
看上去和回调函数有些不一样,在使用Promise进行异步处理的时候,我们必须按照接口规定的方法编写处理代码。
也即是说,除了使用Promise规定的方法(上面的then
和catch
),其他的方法都是不能使用的,而回调函数可以自定义回调的参数。
所以,Promise可以将复杂的异步处理轻松的进行模式化,没有理由让你不使用它。
接下来,我们看看怎么把Promise运用到开发中,这个才是大家想了解的。
学习Promise
在运用到开发之前,我们有必要先学习一些Promise的基本API(暂时看的有点糊涂没关系,等会的例子实践会和大家讲清楚的)。
目前大致有下面三种类型:
1.Constructor(构造器)
我们从构造函数Promise
来创建一个新promise
对象作为接口。
要创建一个promise
对象,可以使用new
来调用Promise
构造器来进行实例化。
|
|
2.Instance Method(实例方法)
在通过new
生成的promise
对象时,我们设置了在resolve(成功)和reject(失败)时调用的回调函数,我们可以使用promise.then()
实例方法。
|
|
resolve(成功)时:
onFulfilled
会被调用reject(失败)时:
onReject
会被调用
onFulfilled
和onReject
都为可选参数
promise.then
成功和失败时都可以使用,另外在异常处理时,可以使用promise.then(undefined, onReject)
这种方式,只指定reject
时的回调函数即可。不过这种情况下,使用promise.catch()
是个明智之选。
|
|
3.Static Method(静态方法)
像promise.all()
和Promise.resolve()
等在内,主要都是一些辅助方法(可以理解为一些语法糖),这里不作深入探讨。
运用在开发中
我们先来看一段Promise使用流程代码:
|
|
分析一下上面代码。
执行(1)
处函数,会返回一个Promise对象,Promise对象内部在300ms后执行resolve()
方法,这个方法调用(2)
处的then()
方法,并传入参数,如果Promise对象内部出现任何错误(比如平台不支持setTimeout方法),就会执行(3)
处的catch()
发放,并把错误作为参数传入。
这里提一下,我看到很多朋友把Promise理解为Ajax的一种扩展,其实并不是这样的,Ajax只是一种请求数据的方式,因为Ajax是异步的,所以我们可以用Promise去管理Ajax请求,但这并不意味这Promise只服务于Ajax,只要是异步处理,我们都可以使用Promise去处理,就比如上面的
setTimeout
。
看到这里大家对Promise应该有一个大概的认识了,实际开发中Promise大部分时间还是搭配Ajax使用,我们来看看应该怎么做,下面用原生的方式请求Ajax,大家也温习一下:
|
|
getURL
只有在XHR取得状态为200时才会调用resolve
,也就是数据取得成功时,而其他情况(数据取得失败)则会调用reject
。
当调用resolve(req.responseText)
时,then
方法也会被调用,并接收到req.responseText
参数。
熟悉Node.js的朋友在写回调时会会将callback(error,response)
的第一个参数设为error
对象,在Promise中,resolve(成功)/reject(失败)担当了这个职责。
XHR中onerror
触发时,就是发生错误时,理所当然要调用reject
,我们重点来看下传给reject
的值。
发生错误时要像这样reject(new Error(req.statusText))
,创建一个Error对象再讲具体的值传入进去。传给reject
的值也没有什么特殊限制,一般只要是Error对象(或继承自Error对象)即可。
小结
其实你理解了Promise的运作流程,使用它十分方便和简单,它就是一个异步管理器,帮助我们更好地去进行异步处理。
试想,如果Promise真的很复杂,那它出现的意义是什么?本末倒置了,哈哈。
本文作者:余震(Freak)
本文出处:Rockjins Blog
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN许可协议。转载请注明出处!