您的位置:首页> 前端教程> ES6教程
文章导航

JavaScript Promise 对象

2019-4-24 22:26| 作者: admin| 查看: 726| 评论: 3|来自: 蚂蚁部落

JavaScript异步操作在实际项目应用广泛,否则一些当前司空见惯的操作就会将浏览器卡死。

举两个比较常见的JavaScript异步操作,一个是ajax操作,另一个是FileReader读取计算机文件。

ajax读取远程服务器数据和FileReader读取计算机文件的时候,不会阻塞其他操作。

当数据或者文件读取完毕之后,然后通过一个回调函数来执行相应的操作。

通过回调函数来完成异步操作是过去不二的选择,但是有一个问题。

看如下代码片段:

[JavaScript] 纯文本查看 复制代码
fs.readFile(fileA, function (err, data) {
  fs.readFile(fileB, function (err, data) {
    //code
  });
});

上面是一个简单的回调函数应用的代码片段,非常的简单,具有两层嵌套。

但是存在一个问题,那么就是回调函数较多的时候,层层嵌套,代码刻度行变的非常差。

可以想象代码会成为什么样子,在横向上会变得非常长,一定非常壮观,会可以说乱花渐欲迷人眼。

上述过多层层嵌套的现象也可以被称作"回调地狱",本文将要介绍的Promise就是为了解决此问题。

一.Promise介绍:

此对象在ES2015被标准化,是一个全新的异步解决方案,能够很好的避免"回调地狱"现象。

事实上在标准化之前,此对象已经在应用,下面对其特点简单总结如下:

(1).Promise对象可以保存异步操作的结果。

(2).Promise异步操作具有三种状态,Pending、Resolved和Rejected。

(3).Promise对象状态的改变可能存在两种情况,Pending到Resolved或者Pending到Rejected。

(4).Promise对象的状态一旦确定,那么就无法改变,要么是Resolved,要么是Rejected。

特别说明:Pending表示等待状态,Resolved表示处于完成状态,Rejected处于未完成状态。

首先通过简单代码片段看一下演示一下Promise对象的应用:

[JavaScript] 纯文本查看 复制代码
let p = new Promise(function(resolve, reject) {
  if (条件是否成立){
    resolve(value);
  } else {
    reject(error);
  }
});

下面对上述代码进行一下简单分析:

(1).通过构造函数可以创建一个Promise对象实例,构造函数的参数是一个回调函数。

(2).构造函数的回调函数具有两个函数参数,由引擎提供,也就是不需要我们提供。

(3).执行resolve函数,那么状态变为Resolved,执行reject函数,状态变为Rejected。

(4).构造函数调用后,回调函数会立马执行,然后根据调用的是resolve还是reject函数,确定状态。

(5).状态确定后,再利用then方法执行对应的操作。下面再来看一段代码片段:

[JavaScript] 纯文本查看 复制代码
p.then(function(value) {
  //code
}, function(value) {
  //code
});

代码分析如下:

(1).then方法的参数是两个回调函数。

(2).如果p处于Resolved完成状态,那么执行第一个回调函数,如果处于Rejected状态。

(3).回调函数中的参数value,分别是传递给resolve和reject函数的参数。

(3).第二回调函数是可以省略的。

[JavaScript] 纯文本查看 复制代码运行代码
let p = new Promise(function (resolve, reject) {
    resolve("蚂蚁部落");
})
p.then(function (val) {
    console.log(val) 
})

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201904/24/222819ip6638lxnhq8omax.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

代码简单分析如下:

(1).执行构造函数Promise,立马执行回调函数,也就会立马调用resolve()函数,参数是"蚂蚁部落"。

(2).于是p的状态变为Resolved,然后执行then函数,进而执行其第一个回调函数,最后打印"蚂蚁部落"。

[JavaScript] 纯文本查看 复制代码运行代码
let p = new Promise(function (resolve, reject) {
  console.log("蚂蚁部落一");
  resolve("蚂蚁部落二");
})
p.then(function (val) { 
  console.log(val) 
})
console.log("蚂蚁部落三");

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201904/24/222853f0y8j38n8xs35n7f.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

代码分析如下:

(1).执行Promise构造函数之后,立马执行其回调函数,于是"蚂蚁部落一"被打印。

(2).然后执行resolve("蚂蚁部落二"),p的状态变为Resolved,于是执行then方法,打印"蚂蚁部落二"

(3).最后再打印"蚂蚁部落三",然而事实是首先打印"蚂蚁部落三",再打印"蚂蚁部落二"。

(4).即便调用resolve("蚂蚁部落二")不存在任何延迟,甚至可以认为是同步进行,但整体依然是异步操作。

看如下代码实例:

[JavaScript] 纯文本查看 复制代码运行代码
setTimeout(function(){
  console.log(index);
},0); 
console.log("蚂蚁部落");

代码运行效果截图如下:

a:3:{s:3:\"pic\";s:43:\"portal/201904/24/222922woxql7l9xoye3p8v.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

虽然延迟实现为0,但是setTimeout是异步操作,所以首先打印'蚂蚁部落二"。

更多内容可以参阅如下两篇文章:

(1).JavaScript 异步操作原理一章节。

(2).setTimeout(func,0)第二个参数为0分析一章节。

[JavaScript] 纯文本查看 复制代码
let P1 = new Promise(function(resolve, reject){
  //code
});
let P2 = new Promise(function (resolve, reject) {
  //code
  resolve(P1);
})

代码片段分析如下:

(1).传递给resolve和reject函数除了普通数据之外,可以是Promise对象实例。

(2).上述代码中,P2的状态由P1的状态决定,非常简单,就不通过完整代码实例演示。

上面已经对Promise对象做了比较详细的总体介绍,此对象还有其他涉及的方法。

考虑到文章的篇幅问题,本文不再做介绍,下面会给出对应文章的链接,可以自行参阅。

如果对本文有任何意见或者建议,可以在文章底部留言,本站会第一时间回复。

二.相关阅读:

(1).Promise.prototype.then() 方法一章节。

(2).Promise.prototype.catch()方法一章节。

(3).Promise.all()方法一章节。

(4).Promise.race()方法一章节。

(5).Promise.resolve()方法一章节。

(6).Promise.reject()方法一章节。

2

鲜花
1

握手

雷人

路过

鸡蛋

刚表态过的朋友 (3 人)

发表评论

最新评论

引用 admin 2019-7-4 19:53
前端继承者: 然而事实是首先打印 蚂蚁部落二,再打印蚂蚁部落三。写错了吧,然而事实是首先打印 蚂蚁部落三,再打印 ...
非常感谢指正,上述表述确实出现笔误,已经修正。
引用 前端继承者 2019-6-30 01:39
然而事实是首先打印"蚂蚁部落二",再打印"蚂蚁部落三"。写错了吧,然而事实是首先打印"蚂蚁部落三",再打印"蚂蚁部落二"。
引用 leone 2019-6-12 15:29
相关阅读链接没有了

查看全部评论(3)

返回顶部