前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript 递归优化

JavaScript 递归优化

作者头像
李振
发布2021-11-26 15:03:36
6080
发布2021-11-26 15:03:36
举报
文章被收录于专栏:乱码李乱码李

简介

异步操作一直都是 JavaScript 中一个比较麻烦的事情,从最早的 callback hell,到TJ大神的 co,再到 Promise 对象,然后ES6中的 Generator 函数,每次都有所改进,但都不是那么彻底,而且理解起来总是很复杂。

直到 async/await 出现,让写异步的人根本不用关心它是不是异步,可以说是目前最好的 JavaScript 异步解决方案。

ECMAScript 2016(ES7) 中已经确定支持 async/await,那我们怎么能够落后呢?

本文是 async/await 的学习笔记,涵盖基本用法以及一些小 demo。

async 函数是什么

阮一峰的 Blog async 函数的含义和用法, 对async的定义一语中的:async 函数就是 Generator 函数的语法糖。

假如有一个Generator函数:

'use strict';
const f = (time) => {
    return new Promise(function (resolve) {
        setTimeout(() => {
            resolve(time);
        }, time);
    });
};

const gen = function* () {
    const f1 = yield f(1000);
    const f2 = yield f(2000);
};

调用方法:

let generator = gen();

let ret = generator.next();
ret.value.then((data)=> {
    console.log(data);
    let ret1 = generator.next(data);
    ret1.value.then(function (data) {
        generator.next(data);
    })
});

将 gen 函数写成 async 函数,就是下面这样:

const asyncF = async(()=> {
    let f1 = await(f(1000));
    let f2 = await(f(2000));
});

一比较就会发现,async 函数就是将 Generator 函数的星号(*)替换成 async,将 yield 替换成 await,仅此而已。

说明

由于目前的大部分浏览器和 NodeJS 环境还不支持 async/await,所以本文程序借助 “asyncawait” 实现,需要额外安装

$ npm install asyncawait

当然如果你对 babel 比较熟悉的话,也可以通过 babel 将 async/await 编译为 ES5,就可直接运行了。

async/await 使用规则

  • async 表示这是一个async函数,await只能用在这个函数里面。
  • await 如果后面是异步函数,跟在后面的应该是一个Promise对象。
  • await 表示在这里等待Promise返回结果了,再继续执行。

获得返回值

可以看到使用 Generator 的时候获取返回值必须使用 .then() 方法,而使用 async/await 就简单很多:

'use strict';
let async = require('asyncawait/async');
let await = require('asyncawait/await');

const f = (time) => {
    return new Promise(function (resolve) {
        setTimeout(() => {
            resolve(time);
        }, time);
    });
};

(async(()=> {
    let f1 = await(f(1000));
    console.log(f1);
    let f2 = await(f(2000));
    console.log(f2);
}))();

await 等待的虽然是 promise 对象,但不必写使用 .then(),也可以得到返回值。

捕捉异常

既然 .then() 不用写了,那 .catch()也不用写,可以直接用标准的try catch语法捕捉错误

const f = (time) => {
    return new Promise(function (resolve, reject) {
        setTimeout(() => {
            reject(new Error('error'));
        }, time);
    });
};

(async(()=> {
    try {
        await(f(3000));
    } catch (err) {
        console.log(err.message); // 这里捕捉到错误 `error`
    }
}))();

await 命令后面的 Promise 对象,运行结果可能是 rejected,所以最好把 await 命令放在 try…catch 代码块中

循环使用 await

await 最好用的地方是可以写在 for 循环里面,这是Promise无法做到的,使得 async/await 看起来更像是同步代码

const f = (time) => {
    return new Promise(function (resolve) {
        setTimeout(() => {
            resolve(time);
        }, time);
    });
};
(async(()=> {
    for (var i = 1; i <= 10; i++) {
        console.log(`当前是第${i}次等待..`);
        await(f(1000));
    }
}))();
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-11-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
    • async 函数是什么
      • 说明
    • async/await 使用规则
      • 获得返回值
        • 捕捉异常
          • 循环使用 await
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档