javascript ES6 新特性之 Promise,ES7 async / await

摘要:
自从推出es6.1varp=newPromise以来,Promise一直受到大家的关注;7页。则;//zhangsan的上述代码等价于以下内容:1函数getData{2setTimeout6}78varp=newPromise;910页。则;//我们可以看到Promise构造函数接受函数作为参数。函数中有两个参数:resolve和reject。Resolve是执行成功的函数,reject是执行失败的函数。如下所示:1函数getData{2setTimeout10}1112varp=newPromise;1314页。然后我们定义一个随机数。当随机数小于0.5时,将遵循p.then()的第一个函数,即正确的分辨率。当随机数大于0.5时,将遵循第二个函数,即错误拒绝。

es6 一经推出,Promise 就一直被大家所关注。那么,为什么 Promise 会被大家这样关注呢?答案很简单,Promise 优化了回调函数的用法,让原本需要纵向一层一层嵌套的回调函数实现了横向的调用,也就是链式调用。

我们先来看下面的代码:

1 function getData(){
2     setTimeout(()=>{
3         var name = "zhangsan";
4     }, 1000)
5 }
6 
7 getData();

在上面的代码中,我们模拟了一个异步时间,一秒后输出 name = "zhangsan"; 那如何当我们调用 getData() 方法的时候拿到这个 name 值呢,这时可能会有人说 return 出来就可以了,如下:

1 function getData(){
2     setTimeout(()=>{
3         var name = "zhangsan";
4     }, 1000);
5     return name
6 }
7 
8 console.log(getData()); // ReferenceError: name is not defined

结果却报错,这时由于当我们执行 getData() 函数的时候,由于 setTimeout 异步执行,所以先执行第五行的 return name;一秒之后才声明 name = "zhangsan"; 所以会 name is not defined 的错。

那有人可能就会说把 return 放到 setTimeout 里面执行,如下:

1 function getData(){
2     setTimeout(()=>{
3         var name = "zhangsan";
4         return name
5     }, 1000);
6 }
7 
8 console.log(getData()); // undefined

仍然拿不到 name 值,报 undefined 的错,这个原因就很简单了,因为执行 getData() 的时候,方法没有返回值,所以报 undefined,一秒之后再执行 setTimeout。

通过以上报错我们可以知道,setTimeout 执行完成后才能拿到 name 的值,所以我们就需要在执行结束后再通过回调的方式拿到 name 的值,如下:

 1 function getData(callback){
 2     setTimeout(()=>{
 3         var name = "zhangsan";
 4         callback(name)
 5     }, 1000)
 6 }
 7 
 8 getData((data)=>{
 9     console.log(data) // zhangsan
10 });

我们在 getData() 方法内出入一个回调函数,当 setTimeout 执行结束后调用此方法并将 name 值传入,这样我们就能拿到 name 值了。这里我们用到了 ES6 的另一个特性 箭头函数,我们姑且先将它 ( ) => { } 和 function( ){ } 看做是等价的。

上述方法可以解决我们的问题,但是在代码上我们就需要再多些一个回调函数,这样看起来很不友好,所以 ES6 为我们提供了 Promise 这个特性。

1 var p = new Promise((resolve, reject) => {
2     setTimeout(() => {
3         var name = "zhangsan";
4         resolve(name)
5     }, 1000)
6 });
7 p.then((data) => {
8     console.log(data);
9 });  // zhangsan

上面的代码等同于下面的:

 1 function getData(resolve, reject) {
 2     setTimeout(() => {
 3         var name = "zhangsan";
 4         resolve(name)
 5     }, 1000)
 6 }
 7 
 8 var p = new Promise(getData);
 9 
10 p.then((data)=> {
11     console.log(data);
12 });  // zhangsan

我们可以看出,Promise 构造函数接受一个函数作为参数,函数里面有两个参数 resolve 和 reject ,其中 resolve 作为执行成功的函数, reject 作为执行失败的函数。如下:

 1 function getData(resolve, reject) {
 2     setTimeout(() => {
 3         var name = "zhangsan";
 4         if(Math.random() < .5){
 5             resolve(name)
 6         } else{
 7             reject("获取 name 失败")
 8         }
 9     }, 1000)
10 }
11 
12 var p = new Promise(getData);
13 
14 p.then((data)=> {
15     console.log(data);   // zhangsan
16 },(data)=>{
17     console.log(data);   // 获取 name 失败
18 }) ;

我们定义一个随机数,当随机数小于 0.5 时会走 p.then() 的第一个函数,也就是正确的 resolve,当随机数大于 0.5 时,会走第二个函数,也就是错误的 reject。

Promise 除了 then 之外还提供了一个一个 catch 的方法,如下:

 1 function getData(resolve, reject) {
 2     setTimeout(() => {
 3         var name = "zhangsan";
 4         resolve(name)
 5     }, 1000)
 6 }
 7 
 8 var p = new Promise(getData);
 9 
10 p.then((name)=> {
11     console.log(name);   // zhangsan
12     console.log(age)
13 }).catch((reason)=>{
14     console.log(reason)  // ReferenceError: age is not defined
15 }) ;

在上面的代码中我们在 p.then() 的方法内输出了一个 age ,但是这个 age 我们既没有在全局定义,也没有通过传值的方式传过来,如果我们不写底下的 catch() 方法的话会报 ReferenceError: age is not defined,同时程序会崩掉,加上 .chath 方法后 ReferenceError: age is not defined 会在此方法内输出,程序并不会崩掉,这个就类似于我们常用的 try / catch 方法。

在 ES7 中,还给我们提供了更为方便的异步操作方法 async / await ;如下:

 1 async function getData() {
 2     return new Promise((resolve, reject) => {
 3         setTimeout(() => {
 4             var name = "zhangsan";
 5             resolve(name)
 6         }, 1000)
 7     })
 8 }
 9 
10 async function test() {
11     var data = await getData();
12     console.log(data);
13 }
14 
15 test();  // zhangsan

我们将之前的代码改为上面这样,输出结果依然是 zhangsan,这里使用了 async / await 的组合,我们将上面的代码简化一下:

 1 async function getData() {
 2     var name = "zhangsan";
 3     return name;
 4 }
 5 
 6 console.log(getData());  // Promise { 'zhangsan' }
 7 
 8 async function test(){
 9     var data = await getData();
10     console.log(data);
11 }
12 
13 test();  // zhangsan

我们在 function getData( ){ } 前面加了一个 async 的字段,该函数就被认定为一个异步函数,然后在调用 getData( ) 的方法前面加一个 await 的字段,这就是一个异步操作,意思就是等 getData( ){ } 异步函数执行完以后再调用此方法,这样我们在 getData() 的函数内加一个 setTimeout 的异步方法后,也是等异步方法执行完以后在调用,这样就能拿到 name = "zhangsan" 的值了。

免责声明:文章转载自《javascript ES6 新特性之 Promise,ES7 async / await》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇pytest中xfail、xpass、skip的简单使用ASP.NET MVC 5 Web编程5 -- 页面传值的方式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

JavaScript异步编程 ( 一 )

1. 异步编程   Javascript语言的执行环境是"单线程"(single thread)。所谓"单线程",就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览...

Echart 动态生成series数据

要做成页面只传入数据,js生成图表,如下图 下面是js代码 var LineChart = function (ID, title, axisData,seriesData) { var myChart = echarts.init(document.getElementById(ID)); var newData = [];...

ES6规范

一、简介 js由三部分组成:ES+DOM(文档对象模型)+ BOM(浏览器对象模型) ES作为核心,是一套标准,规范了语言的组成部分:语法、类型、语句、关键字、保留字。定义了数据结构和语法,定义了函数和对象的实现,包括原型链和作用域链的机制和实现。 JavaScript 的核心 ECMAScript 描述了该语言的语法和基本对象; DOM 描述了处理网页内...

extjs 设置TreePanel CheckBox三态选中

对于TreePanel的Node我们需求是:1.选中某个节点A的CheckBox,节点A的所有子节点全部选中;2.节点A的所有子节点如果都选中,则A节点选中;3.节点A的某些节点选中,某些节点不选中,则A节点处于半选状态。如下图所示: 如何来实现呢? 研究发现TreePanel的节点的Checkbox可发现通过node.getUI().checkbox可...

Promise 对象

Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从...

setTimeout、Promise、Async/Await 的区别

1、setTimeout console.log('script start') //1. 打印 script start setTimeout(function(){ console.log('settimeout') //4. 打印 settimeout }) //2. 调用 setTimeout 函数,并定义其完成后执...