• 7座水库新纳入联合调度 今年汉江防洪能力再提升 2019-09-14
  • 北新建材荣登“中国500最具价值品牌”100强 2019-09-14
  • 【加拿大房产网加拿大新房加拿大房产信息网】 2019-08-27
  • 中考期间广州部分公交线路有调整 2019-08-10
  • 拉萨市第三高级中学举行“四讲四爱”教育实践活动之军民共建协议签订仪式 2019-07-13
  • IP定向新闻--贵州频道--人民网 2019-07-12
  • 国际足联成员也就是亚足联成员的中国(大陆)、朝鲜、中华台北、香港、澳门,也可以有蒙古,可联合申办2038年世界杯。其中,中国大陆、朝鲜,算东道主,直接参赛。 2019-07-02
  • 端午三件套了解一下!这些小知识让你端午更健康 2019-06-28
  • 明星们吃掉一公斤辣椒的瘦身法靠谱吗? 2019-06-28
  • 以仪式守护节日文化(艺海观澜) 2019-06-22
  • 《紫砂的意蕴——宜兴紫砂工艺研究》简介 2019-06-21
  • 点评:世界杯八大热门亮相完毕 西班牙巴西最有冠军相 2019-06-21
  • 大家都误解蔡英文了?台专家酸讽:台湾的问题出在2300万人身上 2019-06-17
  • 五一游记:随华商网乡村游走进安康 游览南宫山 蜀河古镇 2019-06-17
  • 俄罗斯5-0沙特!看球之余俄罗斯还有哪些能玩的地?--旅游频道 2019-06-12
  • 全国咨询热线:400-618-4000

    pk10大小单双在线计划:目前最好的js异步

    pk10什么叫跨度去一尾 www.9i8s.com.cn 创建时间:2019年01月10日15时19分

    构建一个应用程序总是会面对异步调用,不论是在 Web 前端界面,还是 Node.js 服务端都是如此,JavaScript 里面处理异步调用一直是非常恶心的一件事情。以前只能通过回调函数,后来渐渐又演化出来很多方案,最后 Promise 以简单、易用、兼容性好取胜,但是仍然有非常多的问题。其实 JavaScript 一直想在语言层面彻底解决这个问题,在 ES6 中就已经支持原生的 Promise,还引入了 Generator 函数,终于在 ES7 中决定支持 async 和 await。
    基本语法
    async/await 究竟是怎么解决异步调用的写法呢?简单来说,就是将异步操作用同步的写法来写。先来看下最基本的语法(ES7 代码片段):
    [JavaScript] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    const f = () => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(123);
        }, 2000);
      });
    };
     
    const testAsync = async () => {
      const t = await f();
      console.log(t);
    };
     
    testAsync();
    首先定义了一个函数 f,这个函数返回一个 Promise,并且会延时 2 秒,resolve 并且传入值 123。testAsync 函数在定义时使用了关键字 async,然后函数体中配合使用了 await,最后执行 testAsync。整个程序会在 2 秒后输出 123,也就是说 testAsync 中常量 t 取得了 f 中 resolve 的值,并且通过 await 阻塞了后面代码的执行,直到 f 这个异步函数执行完。
    对比 Promise
    仅仅是一个简单的调用,就已经能够看出来 async/await 的强大,写码时可以非常优雅地处理异步函数,彻底告别回调恶梦和无数的 then 方法。我们再来看下与 Promise 的对比,同样的代码,如果完全使用 Promise 会有什么问题呢?
    [JavaScript] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    const f = () => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(123);
        }, 2000);
      });
    };
     
    const testAsync = () => {
      f().then((t) => {
        console.log(t);
      });
    };
     
    testAsync();
    从代码片段中不难看出 Promise 没有解决好的事情,比如要有很多的 then 方法,整块代码会充满 Promise 的方法,而不是业务逻辑本身,而且每一个 then 方法内部是一个独立的作用域,要是想共享数据,就要将部分数据暴露在最外层,在 then 内部赋值一次。虽然如此,Promise 对于异步操作的封装还是非常不错的,所以 async/await 是基于 Promise 的,await 后面是要接收一个 Promise 实例。

    异常处理
    通过使用 async/await,我们就可以配合 try/catch 来捕获异步操作过程中的问题,包括 Promise 中 reject 的数据。
    [JavaScript] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    const f = () => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(234);
        }, 2000);
      });
    };
    const testAsync = async () => {
      try {
        const t = await f();
        console.log(t);
      } catch (err) {
        console.log(err);
      }
    };
    testAsync();
    代码片段中将 f 方法中的 resolve 改为 reject,在 testAsync 中,通过 catch 可以捕获到 reject 的数据,输出 err 的值为 234。try/catch 使用时也要注意范围和层级。如果 try 范围内包含多个 await,那么catch 会返回第一个 reject 的值或错误。
    [JavaScript] 纯文本查看 复制代码
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    const f1 = () => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(111);
        }, 2000);
      });
    };
    const f2 = () => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(222);
        }, 3000);
      });
    };
    const testAsync = async () => {
      try {
        const t1 = await f1();
        console.log(t1);
        const t2 = await f2();
        console.log(t2);
      } catch (err) {
        console.log(err);
      }
    };
    testAsync();
    如代码片段所示,testAsync 函数体中 try 有两个 await 函数,而且都分别 reject,那么 catch 中仅会触发 f1 的 reject,输出的 err 值是 111。
    开始使用
    无论是 Web 前端还是 Node.js 服务端,都可以通过预编译的手段实现使用 ES6 和 ES7 来写代码,目前最流行的方案是通过 [color=var(--link-color)]Babel 将使用 ES7、ES6 写的代码编译为 E6 或 ES5 的代码来执行。
    Node.js 服务端配置
    服务端使用 Babel,最简单的方式是通过 require hook。
    首先安装 Babel:
    $ npm install babel-core --save
    安装 async/await 支持:
    $ npm install babel-preset-stage-3 --save
    在服务端代码的根目录中配置 .babelrc 文件,内容为:
    {  "presets": ["stage-3"]}
    在顶层代码文件(server.js 或 app.js 等)中引入 Babel ??椋?/font>
    require("babel-core/register");
    在这句后面引入的???,都将会自动通过 babel 编译,但当前文件不会被 babel 编译。另外,需要注意 Node.js 的版本,如果是 4.0 以上的版本则默认支持绝大部分 ES6,可以直接启动。但是如果是 0.12 左右的版本,就需要通过 node -harmony 来启动才能够支持。因为 stage-3 模式,Babel 不会编译基本的 ES6 代码,环境既然支持又何必要编译为 ES5?这样做也是为了提高性能和编译效率。
    配置 Web 前端构建
    可以通过增加 Gulp 的预编译 task 来支持。
    首先安装 gulp-babel 插件:
    $ npm install gulp-babel --save-dev
    然后编写配置:

    [JavaScript] 纯文本查看 复制代码
    1
    2
    3
    4
    5
    6
    7
    8
    var gulp = require('gulp');
    var babel = require('gulp-babel');
    gulp.task('babel', function() {
      return gulp.src('src/app.js')
        .pipe(babel())
        .pipe(gulp.dest('dist'));
    });
    除了 Gulp-babel 插件,也可以使用官方的 Babel-loader 结合 Webpack 或 Browserify 使用。
    要注意的是,虽然官方也有纯浏览器版本的 Babel.js,但是浏览器限制非常多,而且对客户端性能影响也较大,不推荐使用。


    作者:传智播客前端与移动开发培训学院

    首发: //web.www.9i8s.com.cn

  • 7座水库新纳入联合调度 今年汉江防洪能力再提升 2019-09-14
  • 北新建材荣登“中国500最具价值品牌”100强 2019-09-14
  • 【加拿大房产网加拿大新房加拿大房产信息网】 2019-08-27
  • 中考期间广州部分公交线路有调整 2019-08-10
  • 拉萨市第三高级中学举行“四讲四爱”教育实践活动之军民共建协议签订仪式 2019-07-13
  • IP定向新闻--贵州频道--人民网 2019-07-12
  • 国际足联成员也就是亚足联成员的中国(大陆)、朝鲜、中华台北、香港、澳门,也可以有蒙古,可联合申办2038年世界杯。其中,中国大陆、朝鲜,算东道主,直接参赛。 2019-07-02
  • 端午三件套了解一下!这些小知识让你端午更健康 2019-06-28
  • 明星们吃掉一公斤辣椒的瘦身法靠谱吗? 2019-06-28
  • 以仪式守护节日文化(艺海观澜) 2019-06-22
  • 《紫砂的意蕴——宜兴紫砂工艺研究》简介 2019-06-21
  • 点评:世界杯八大热门亮相完毕 西班牙巴西最有冠军相 2019-06-21
  • 大家都误解蔡英文了?台专家酸讽:台湾的问题出在2300万人身上 2019-06-17
  • 五一游记:随华商网乡村游走进安康 游览南宫山 蜀河古镇 2019-06-17
  • 俄罗斯5-0沙特!看球之余俄罗斯还有哪些能玩的地?--旅游频道 2019-06-12