ES6新标准下JS异步编程Promise解读

简介: ES6新标准下JS异步编程Promise解读

ES5及以下,要实现复杂的异步编程,需要大量运用回调函数,每一个回调函数(JS引擎把它当作一个代码块)依次进入单线程(JS)任务队伍依次执行,而每个回调函数中的执行正确与否无法及时判断,当中信息反馈及显示都只会在最外层函数执行完毕后才反馈给你,让你只能猜测或分析找问题,这将造成大量无法理解的情况出现。对于复杂嵌套回调问题,你将不得不花费大量精力去跟踪各个回调函数运行及清理相互影响。

ES6新标准引入Promise对上述问题进行解决,它的核心思想,是将上一次函数执行返回一个Promise对象,明确指示代码是否成功执行,则你可以基于此成功与否判断,以链式编程方式将复杂嵌套回调函数转换为简单流程化式的形式完成目标任务。

一、Promise的基本用法

每个Promise都会经历一个短暂的生命周期,当处于进行中时标记为pending状态,一旦异步操作结束,Promise标记为settled状态,如果操作出现错误或未完成,标记为unsettle状态。其内部属性[[PromiseState]],分别对应这三种状态,分别是”pending”、“fulfilled”和”rejected”。其内部会自动调用then()方法响应fulfilled成功状态,catch()方法响应rejected。

Then()方法调用时,与异步操作相关的附加数据都会传递给这个完成响应函数。Catch()调用时,所有与失败状态相关的附加数据都会传递给这个拒绝响应函数。

1.基本用法

Promise构造函数可以创建Promise,构造函数接受两个参数,分别是resolve()函数与reject()函数,执行成功完成时调用resolve()函数,失败时则调用reject()函数。

Promise.resolve方法是将一个对象转换成Promise对象,如果入参是一个Promise对象,则直接返回该对象;如果入参是一个thenale对象(表示该对象已经调用了then方法),则返回的是一个新的Promise对象;如果无任何参数,则返回一个fulfilled状态的Promise对象。

Promise.reject方法可以快速返回被rejected的Promise对象。该方法接收一个参数作为入参,这个参数将成来被rejected对象的reason属性,传给rejected回调函数。

   let promise1=new Promise(function(resolve,reject){//模拟函数成功执行

          resolve("成功");

   });

   promise1.then(function(contents){

          console.log(contents);//输出---成功

   });

   let promise2=new Promise(function(resolve,reject){//模拟函数拒绝执行

          reject(new Error("拒绝"));

   });

   promise2.catch(function(err){

          console.log(err);//输出---Error:拒绝

   });

2.具体运用实例

function readNumber(num){//定义Promise实例函数

   return new Promise(function(resolve,reject){

                 if(num<0){

                        reject("输入的数字小于0,拒绝兑换");

                        return;

                 }

                 resolve("输入的数字大于0,执行兑换");

   });

}

let promise1=readNumber(45);//执行成功输入

promise1.then(function(contents){

   console.log(contents);//输出结果:输入的数字大于0,执行兑换

});

promise1.catch(function(err){

   console.log(err);//此函数不会被调用,故无此输出

});

let promise2=readNumber(-6);//执行失败输入

promise2.then(function(contents){

   console.log(contents);//此函数不会被调用,故无此输出

});

promise2.catch(function(err){

   console.log(err);//输入的数字小于0,拒绝兑换

});

二、Promise的串联(链式)用法

Promise每次调用then()方法和catch()方法时,实际上创建了另一个Promise,只有当第一个Promise完成或被拒绝时,第二个才会被解决。因此,就给解决复杂问题链式化提供了条件,而不是用复杂或嵌套式回调函数去解决。其写法如下:

Let p1=new Promise(function(resolve,reject){ });

P1.then(function(){ }).then(funciton(){ })…

以上述实例为具体实现,如下:

function readNumber(num){//定义Promise实例函数

   return new Promise(function(resolve,reject){

                 if(num<0){

                        reject("输入的数字小于0,拒绝兑换");

                        return;

                 }

                 resolve("输入的数字大于0,执行兑换");

   });

}

let promise1=readNumber(45);//执行成功输入

promise1.then(function(contents){

   console.log(contents);//输出结果:输入的数字大于0,执行兑换

}).then(function(){

   console.log("由于有兑换劵,就可以进入购买了");//输出结果:由于有兑换劵,就可以进入购买了

});

let promise2=readNumber(-8);//执行失败输入

promise2.then(function(contents){

   console.log(contents);//输出结果:输入的数字大于0,执行兑换

}).then(function(){

   console.log("由于有兑换劵,就可以进入购买了");//无输出结果:由于readeNumber输入的是-8,第一个then不满足,为拒绝状态,因而第二个then没有调用,而第三个then是基于第二个then呈错误状态的,所有第三个then被执行

}).catch(function(){

   console.log("由于没有有兑换劵,无法进入");//输出结果:由于没有有兑换劵,无法进入

})

三、多Promise响应用法

如果你想通过多个Promise来决定下一步的操作,则可以使用ES6提供的Promise.all()和Promise.race()两个方法来监听多个Promise。

1.Promise.all()方法

Promise.all()方法只接受一个参数并返回一个Promise,该参数是一个含有多个受监视Promise的可迭代对象(例如,一个数组),只有当可迭代对象中所的Promise都被解决后返回的Promise才会被解决,只有当可迭代对象中所有Promise都被完成返回后的Promise才会被完成。

let p1=new Promise(function(resolve,reject){

   resolve(42);

});

let p2=new Promise(function(resolve,reject){

   resolve(43);

});

let p3=new Promise(function(resolve,reject){

   resolve(44);

});

let p4=Promise.all([p1,p2,p3]);

p4.then(function(value){ //因为P4呈完成状态,所以没有调用catch,而是调用的then方法

   console.log(Array.isArray(value));//输出结果:true

   console.log(value[0]);//输出结果:42

   console.log(value[1]);//输出结果:43

   console.log(value[2]);//输出结果:44

})

上述例中,只有当迭代中所有都完成,P4才呈完成状态;反之,只要有一个被拒绝,那么返回的Promise没等其他后面Promise完成就立即呈拒绝状态。如下:

let p1=new Promise(function(resolve,reject){

          resolve(42);

   });

   let p2=new Promise(function(resolve,reject){

          reject(43);

   });

   let p3=new Promise(function(resolve,reject){

          resolve(44);

   });

   let p4=Promise.all([p1,p2,p3]);

   p4.catch(function(value){//因为P4呈拒绝状态,所以没有调用then,而是调用的catch方法

          console.log(Array.isArray(value));//输出结果:false

          console.log(value);//输出结果:43

   });

2.Promise.race()方法

Promise.race()方法也监听多个Promise,与Promise.all方法不一样,它只要有一相Promise被解决则立即返回呈解决状态,无须等到所有的Promise都被解决。

let p1=new Promise(function(resolve,reject){

   resolve(42);

});

let p2=new Promise(function(resolve,reject){

   resolve(43);

});

let p3=new Promise(function(resolve,reject){

   resolve(44);

});

let p4=Promise.race([p1,p2,p3]);

p4.then(function(value){//只要p1呈完成状态,就立即返回呈完成状态,其他后面Promise则被忽略

   console.log(Array.isArray(value));//输出结果:false

   console.log(value);//输出结果:42

});

实际上,传给Promise.race()方法的Promise会进行竞选,以决出哪一个先被解决完成,就选哪一个,并以最先解决状态而呈相同状态,其他的则被忽略。

let p1=new Promise(function(resolve,reject){

   setTimeout(function(){resolve(42);},200);

});

let p2=new Promise(function(resolve,reject){

   resolve(43);

});

let p3=new Promise(function(resolve,reject){

   resolve(44);

});

let p4=Promise.race([p1,p2,p3]);

p4.then(function(value){//由于p1被延迟执行,所以p2最先呈完成状态,故最后输出为p2状态

   console.log(Array.isArray(value));//输出结果:false

   console.log(value);//输出结果:43
相关文章
|
5天前
|
前端开发 JavaScript 数据库连接
掌握 JavaScript 异步编程:从回调到 Async/Await
在现代 JavaScript 开发中,异步编程是处理非阻塞操作的关键技术。本文从早期的回调函数讲起,逐步过渡到 Promise 和 ES2017 的 async/await 语法,展示了异步编程如何变得更加简洁和强大。通过实用的技巧和最佳实践,帮助开发者避免常见陷阱,提升代码效率和可靠性。
|
2天前
|
XML JSON 前端开发
JavaScript 异步编程
JavaScript 异步编程
9 3
JavaScript 异步编程
|
1天前
|
JavaScript 前端开发 数据库
探索Node.js中的异步编程模型
【9月更文挑战第23天】在Node.js的世界里,异步编程是核心的魔法,它让这个平台能够处理高并发请求。本文将带你深入理解Node.js的异步编程模型,通过代码示例和直观的解释,我们将一起揭开异步编程的面纱。
26 16
|
3天前
|
前端开发 JavaScript 开发者
探索JavaScript的异步编程之旅
【9月更文挑战第21天】在数字世界中,时间就是一切。本文将带你深入理解JavaScript中的异步编程模式,通过实际代码示例,展示如何高效处理任务,优化用户体验。从回调函数到Promises,再到async/await,我们将一步步解锁JavaScript异步编程的秘密。
|
3天前
|
Web App开发 JavaScript 前端开发
探索Node.js中的异步编程模型
【9月更文挑战第21天】在现代Web开发中,Node.js以其非阻塞I/O和事件驱动的特性成为热门选择。本文将深入探讨Node.js的异步编程模型,揭示其背后的原理,并通过示例代码展示如何高效利用异步特性来处理并发任务。
|
1天前
|
JavaScript 安全
ES6中JS类实现的解读
ES6中JS类实现的解读
11 2
|
2天前
|
前端开发 JavaScript
JavaScript Promise-2
JavaScript Promise-2
10 3
|
2天前
|
Web App开发 前端开发 JavaScript
JavaScript Promise-1
JavaScript Promise
8 3
|
2月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
71 2
|
2月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
64 4