javascript ES6 新特性之 Promise,ES7 async / await
es6 一经推出,Promise 就一直被大家所关注。那么,为什么 Promise 会被大家这样关注呢?答案很简单,Promise 优化了回调函数的用法,让原本需要纵向一层一层嵌套的回调函数实现了横向的调用,也就是链式调用。
我们先来看下面的代码:
function getData(){
setTimeout(()=>{
var name = "zhangsan";
}, 1000)
}
getData();
在上面的代码中,我们模拟了一个异步时间,一秒后输出 name = "zhangsan"; 那如何当我们调用 getData() 方法的时候拿到这个 name 值呢,这时可能会有人说 return 出来就可以了,如下:
function getData(){
setTimeout(()=>{
var name = "zhangsan";
}, 1000);
return name
}
console.log(getData()); // ReferenceError: name is not defined
结果却报错,这时由于当我们执行 getData() 函数的时候,由于 setTimeout 异步执行,所以先执行第五行的 return name;一秒之后才声明 name = "zhangsan"; 所以会 name is not defined 的错。
那有人可能就会说把 return 放到 setTimeout 里面执行,如下:
function getData(){
setTimeout(()=>{
var name = "zhangsan";
return name
}, 1000);
}
console.log(getData()); // undefined
仍然拿不到 name 值,报 undefined 的错,这个原因就很简单了,因为执行 getData() 的时候,方法没有返回值,所以报 undefined,一秒之后再执行 setTimeout。
通过以上报错我们可以知道,setTimeout 执行完成后才能拿到 name 的值,所以我们就需要在执行结束后再通过回调的方式拿到 name 的值,如下:
function getData(callback){
setTimeout(()=>{
var name = "zhangsan";
callback(name)
}, 1000)
}
getData((data)=>{
console.log(data) // zhangsan
});
我们在 getData() 方法内出入一个回调函数,当 setTimeout 执行结束后调用此方法并将 name 值传入,这样我们就能拿到 name 值了。这里我们用到了 ES6 的另一个特性 箭头函数,我们姑且先将它 ( ) => { } 和 function( ){ } 看做是等价的。
上述方法可以解决我们的问题,但是在代码上我们就需要再多些一个回调函数,这样看起来很不友好,所以 ES6 为我们提供了 Promise 这个特性。
var p = new Promise((resolve, reject) => {
setTimeout(() => {
var name = "zhangsan";
resolve(name)
}, 1000)
});
p.then((data) => {
console.log(data);
}); // zhangsan
上面的代码等同于下面的:
function getData(resolve, reject) {
setTimeout(() => {
var name = "zhangsan";
resolve(name)
}, 1000)
}
var p = new Promise(getData);
p.then((data)=> {
console.log(data);
}); // zhangsan
我们可以看出,Promise 构造函数接受一个函数作为参数,函数里面有两个参数 resolve 和 reject ,其中 resolve 作为执行成功的函数, reject 作为执行失败的函数。如下:
function getData(resolve, reject) {
setTimeout(() => {
var name = "zhangsan";
if(Math.random() < .5){
resolve(name)
} else{
reject("获取 name 失败")
}
}, 1000)
}
var p = new Promise(getData);
p.then((data)=> {
console.log(data); // zhangsan
},(data)=>{
console.log(data); // 获取 name 失败
}) ;
我们定义一个随机数,当随机数小于 0.5 时会走 p.then() 的第一个函数,也就是正确的 resolve,当随机数大于 0.5 时,会走第二个函数,也就是错误的 reject。
Promise 除了 then 之外还提供了一个一个 catch 的方法,如下:
function getData(resolve, reject) {
setTimeout(() => {
var name = "zhangsan";
resolve(name)
}, 1000)
}
var p = new Promise(getData);
p.then((name)=> {
console.log(name); // zhangsan
console.log(age)
}).catch((reason)=>{
console.log(reason) // ReferenceError: age is not defined
}) ;
在上面的代码中我们在 p.then() 的方法内输出了一个 age ,但是这个 age 我们既没有在全局定义,也没有通过传值的方式传过来,如果我们不写底下的 catch() 方法的话会报 ReferenceError: age is not defined,同时程序会崩掉,加上 .chath 方法后 ReferenceError: age is not defined 会在此方法内输出,程序并不会崩掉,这个就类似于我们常用的 try / catch 方法。
在 ES7 中,还给我们提供了更为方便的异步操作方法 async / await ;如下:
async function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
var name = "zhangsan";
resolve(name)
}, 1000)
})
}
async function test() {
var data = await getData();
console.log(data);
}
test(); // zhangsan
我们将之前的代码改为上面这样,输出结果依然是 zhangsan,这里使用了 async / await 的组合,我们将上面的代码简化一下:
async function getData() {
var name = "zhangsan";
return name;
}
console.log(getData()); // Promise { 'zhangsan' }
async function test(){
var data = await getData();
console.log(data);
}
test(); // zhangsan
我们在 function getData( ){ } 前面加了一个 async 的字段,该函数就被认定为一个异步函数,然后在调用 getData( ) 的方法前面加一个 await 的字段,这就是一个异步操作,意思就是等 getData( ){ } 异步函数执行完以后再调用此方法,这样我们在 getData() 的函数内加一个 setTimeout 的异步方法后,也是等异步方法执行完以后在调用,这样就能拿到 name = "zhangsan" 的值了。
javascript ES6 新特性之 Promise,ES7 async / await的更多相关文章
- javascript ES6 新特性之 扩展运算符 三个点 ...
对于 ES6 新特性中的 ... 可以简单的理解为下面一句话就可以了: 对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中. 作用类似于 Object.assign() ...
- ES6新特性之 promise
新的ES6中引入了promise的概念,目的是让回调更为优雅.层层嵌套的回调会让javascript失去美感和可读性,同时javascript也推荐采用链式的方式去书写函数调用.于是Promise就应 ...
- JavaScript ES6 新特性详解
JavaScript ES6 带来了新的语法和新的强大功能,使您的代码更现代,更易读 const , let and var 的区别: const , let 是 ES6 中用于声明变量的新关键字. ...
- JavaScript ES6新特性介绍
介绍 ES6:ECMScript6 首先,一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系? ECMAScript是一个国际通过的标准化脚本语言: JavaScript ...
- javascript ES6 新特性之 let
let的作用是声明变量,和var差不多. let是ES6提出的,在了解let之前,最好先熟悉var的原理. JavaScript有一个机制叫“预解析”,也可以叫“提升(Hoisting)机制”.很多刚 ...
- javascript ES6 新特性之 class
在之前的文章中我们讲过原型,原型链和原型链继承的文章,在 ES6 中为我们提供了更为方便的 class,我们先来看一下下面的例子: function Person(name) { //构造函数里面的方 ...
- javascript ES6 新特性之 解构
解构的作用是可以快速取得数组或对象当中的元素或属性,而无需使用arr[x]或者obj[key]等传统方式进行赋值 var arr = [1, 2, 3]; //传统方式 var a = arr[0], ...
- 前端入门21-JavaScript的ES6新特性
声明 本篇内容全部摘自阮一峰的:ECMAScript 6 入门 阮一峰的这本书,我个人觉得写得挺好的,不管是描述方面,还是例子,都讲得挺通俗易懂,每个新特性基本都还会跟 ES5 旧标准做比较,说明为什 ...
- ES2015 (ES6) 新特性: 20 个
ES2015 (ES6) 新特性 http://babeljs.io/docs/learn-es2015/ Learn ES2015 A detailed overview of ECMAScript ...
随机推荐
- UOJ#291. 【ZJOI2017】树状数组 树套树
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ291.html 题解 结论:这个写错的树状数组支持的是后缀加和后缀求和.这里的后缀求和在 x = 0 的时 ...
- Java中超大文件读写
如果文件过大不能一次加载,就可以利用缓冲区: File file = new File(filepath); BufferedInputStream fis = new BufferedInputSt ...
- docker使用教程
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Li ...
- HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- 精读《Function VS Class 组件》
1. 引言 为什么要了解 Function 写法的组件呢?因为它正在变得越来越重要. 那么 React 中 Function Component 与 Class Component 有何不同? how ...
- mpvue中使用wxParse,解析a标签跳转问题
安装:npm i mpvue-wxparse js:import wxparse from "mpvue-wxparse"; css:@import url('~mpvue-wxp ...
- scrapy的持久化相关
终端指令的持久化存储 保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作. 需求是:将糗百首页中段子的内容和标 ...
- Unity Rain Ai 插件基本使用(一)
1.下载安装Rain 插件 原先可以在unity的Asset Stroe 下载到,但是现在Rain 的开发公司因为人工智能的发展,公司得到投资,所以下架了rain插件. 所以我给出网盘链接 链接:ht ...
- 使用Cors在WebApi中实现跨域请求,请求方式为angular的 $http.jsonp
使用Cors在WebApi中实现跨域请求 第一步,在webapi项目中安装cors 在Web API配置文件中(Global.asax)进行全局配置: public class WebApiAppli ...
- 极速创建 IOS APP !涛舅舅苹果 IOS APP自助生成系统!不用证书、不用越狱、永久可用
不用签名将网页封装成苹果APP,无需苹果企业签名,IPA签名,ios签名,免越狱安装 (本方法只支持网站封装app,原生的用不了,详细请咨询客服) 近期很多朋友问我把网站变成app的方法,原因很多种, ...