理解promise

前言

在学习node的路上,理解异步操作是重点,而处理的方法一直在完善,先有setTimeout,后又promise,貌似目前目前大招是async/await(目前三个都不理解,(捂脸…)),下面就开始吧。
这是在看JavaScript Promise迷你书时记录的笔记,若有错误,敬请指出,感激不尽。
原文Promise迷你书

1、什么是Promise

1.1、常见异步处理

Promise是抽象异步处理对象以及对其进行操作的组件。
Promise最初被提出是在E语言,E语言是基于并列/并行处理设计的一种编程语言。
常见基于javaScript的异步处理大都利用回调函数

1
2
3
4
5
6
7
8
----
//使用回调函数的异步处理
getAsync("fileA.txt", function(error, result){
if(error){
throw error;
}
});
----

1.2、使用Promise进行异步处理

Promise是把类似的异步处理对象和处理规则规范化,并按照统一的接口来编写,而采取规定方法之外的写法都会出错。

1
2
3
4
5
6
7
8
//使用Promise进行异步处理
var promise = getAsyncPromise("fileA.txt");
promise.then(function(result){
//获取文件内容成功时的处理
}).catch(function(error){
//获取文件内容失败时的处理
});
<1>返回promise对象

我们可以向预设了抽象化异步处理的promise对象,注册这个promise对象执行成功和失败时相应的回调函数。
这里与常见异步处理操作不同,需严格遵守规则,无法自由的定义回调函数的参数。
所以,promise的功能是可以将复杂的异步处理轻松地进行模式化

1.3、Promise简介

三种API类型

Constructor

Promise类似XMLHttpRequest,从构造函数promise新建一个promise对象作为接口。

1
2
3
4
5
//创建promise对象
var promise = new Promise(function(res,rej){
//异步处理
//处理完后,调用resolve或reject
});

Instance Method

通过new生成promise对象,promise.then()方法可以设置在resolve(成功)/reject(失败)时调用的回调函数。
promise.then(onFulfilled, onRejected)

resolve(成功)时

onFulfilled 会被调用

reject(失败)时

onRejected 会被调用
只想对异常进行处理时可以采用 promise.then(undefined, onRejected)这种方式,
只指定reject时的回调函数即可。
不过这种情况下 promise.catch(onRejected) 应该是个更好的选择。

Static Method

辅助方法:
promise.all()
promise.resolve()

1.3.1、Promise workflow

1
2
3
4
5
6
7
8
9
10
11
12
function asyncFunction() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('Async Hello world');
}, 16);
});
}
asyncFunction().then(function (value) {
console.log(value); // => 'Async Hello world'
}).catch(function (error) {
console.log(error);
});

1.3.2、Promise的状态

new Promise实例化的promise对象有以下三个状态:

“has-resolution” - Fulfilled

resolve(成功)时。此时会调用 onFulfilled

“has-rejection” - Rejected

reject(失败)时。此时会调用 onRejected

“unresolved” - Pending

既不是resolve也不是reject的状态。也就是promise对象刚被创建后的初始化状态等
状态变化
"状态变化"

promise对象的状态,从Pending转换为Fulfilled或Rejected之后, 这个promise对象的状态就不会再发生任何变化。
也就是说,Promise与Event等不同,在.then后执行的函数可以肯定地说只会被调用一次。
另外,Fulfilled和Rejected这两个只中任一状态都可以表示为Settled(不变的)。

Settled

resolve(成功)或rejected(失败)。

1.4、编写Promise代码

如何写Promise代码。

1.4.1、创建promise对象

流程如下
1.new Promise(fn)返回一个promise对象

2.在fn中指定异步等处理

* 处理结果正常,调用resolve(处理结果值)
* 处理结果错误,调用reject(Error对象)

在此用Promise来通过异步处理方式来获取XMLHttpRequest(XHR)的数据。

创建XHR的promise对象

首先,创建一个用Promise把XHR处理包装起来的名为getURL的函数。

xhr-promise.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status == 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
}
});
}

//实例
var URL = "http://httpbin.org/get";
getURL(URL).then(function onFulfilled(value){
console.log(value);
}).catch(function onRejected(error){
console.error(error);
});

//输出结果为请求数据

getURL只有在通过XHR取得结果状态码为200(数据取得成功)时,调用resovle,其他情况(取得失败)时调用reject方法。

成功时

resolve(req.responseText)在response的内容中加入了这个参数,resolve方法把参数传给回调函数(then方法会接收这个参数)。

常见回调函数callback(err, response)的值为err(出错)和response(接收的数据),来处理正常和异常的情况,而在Promise中resolve/reject则担当了这个职责

失败时

当发生错误时,onerror事件被触发,调用reject

此时,如reject(new Error(req.statusText)),创建一个Error对象并将具体的值传入,传给reject的参数只要是Error对象(或者继承自Error对象)就行。

我的疑问

-------------本文结束感谢您的阅读-------------
显示 Gitment 评论