【ES6知识】async 函数与代码优雅写法

文章目录

    • [一、async 函数](#一、async 函数)
      • [1.1 async 函数是什么?](#1.1 async 函数是什么?)
      • [1.2 基本用法](#1.2 基本用法)
    • 二、代码优雅写法
      • [2.1 nullish 空值合并运算符 "??"](#2.1 nullish 空值合并运算符 "??")
      • [2.2 防止崩溃的可选链](#2.2 防止崩溃的可选链)
      • [2.3 解构赋值](#2.3 解构赋值)
      • [2.4 将任何值转换为布尔值](#2.4 将任何值转换为布尔值)
      • [2.5 数组组合合并](#2.5 数组组合合并)
      • [2.6 为函数参数提供默认值](#2.6 为函数参数提供默认值)
      • [2.7 将对象的值收集到数组中](#2.7 将对象的值收集到数组中)
      • [2.7 压缩多个条件](#2.7 压缩多个条件)
      • 指数运算符
      • 三、
      • [3.1 模块化](#3.1 模块化)
      • [3.2 ES6新特性参考](#3.2 ES6新特性参考)

一、async 函数

1.1 async 函数是什么?

一句话,它是 Generator 函数的语法糖。ES7 才引入的与异步操作有关的关键字。

原生JavaScipt案例合集
JavaScript +DOM基础
JavaScript 基础到高级
Canvas游戏开发

Generator 函数读取两个文件的代码:

const fs = require('fs');

const readFile = function (fileName) {
  return new Promise(function (resolve, reject) {
    fs.readFile(fileName, function(error, data) {
      if (error) return reject(error);
      resolve(data);
    });
  });
};

const gen = function* () {
  const f1 = yield readFile('/etc/fstab');
  const f2 = yield readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

上面代码的函数gen可以写成async函数,就是下面这样:

const asyncReadFile = async function () {
  const f1 = await readFile('/etc/fstab');
  const f2 = await readFile('/etc/shells');
  console.log(f1.toString());
  console.log(f2.toString());
};

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

1.2 基本用法

async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

await 操作符用于等待一个 Promise 对象, 它只能在异步函数 async function 内部使用。

async function getStockPriceByName(name) {
  const symbol = await getStockSymbol(name);
  const stockPrice = await getStockPrice(symbol);
  return stockPrice;
}

getStockPriceByName('goog').then(function (result) {
  console.log(result);
});

function testAwait(){
   return new Promise((resolve) => {
       setTimeout(function(){
          console.log("testAwait");
          resolve();
       }, 1000);
   });
}
 
async function helloAsync(){
   await testAwait();
   console.log("helloAsync");
 }
helloAsync();
// testAwait
// helloAsync

二、代码优雅写法

2.1 nullish 空值合并运算符 "??"

空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为null或者undefined时,返回其右侧操作数,否则返回左侧操作数。

c 复制代码
function nullish() {
        // 左侧为 null 或者 undefined 返回 ?? 右侧的值
        let maybeSomething;

        // 未优化前
        // if(maybeSomething){
        //   console.log(maybeSomething)
        // } else {
        //   console.log("Nothing found")
        // }

        console.log(maybeSomething ?? "Nothing found"); // 'Nothing found'

        // 不同于 || ,当左侧为一个假值如 "" 或 0 时,返回 ?? 左侧的值
        maybeSomething = false;
        console.log(maybeSomething ?? 200); // false
}

2.2 防止崩溃的可选链

可选链:Optional Chaining Operator 可选链操作符是一个新的js api,它允许读取一个被连接对象的深层次的属性的值而无需明确校验链条上每一个引用的有效性。

c 复制代码
function optChain() {
        const student = {
            name: "Matt",
            age: 27,
            address: {
                state: "New York"
            },
        };
        // 未优化前
        // console.log(student && student.address && student.address.ZIPCode); 
        // 优化代码
        // console.log(student?.address);//{state: "New York"}
        console.log(student?.address?.ZIPCode);
},

使用可选链可以直接在链式调用的时候进行判断,左侧的对象是否为null或undefined,如果是的,就不再往下运算,而是返回undefined,如果不是,则继续往下运算。

2.3 解构赋值

使用解构从数组中拆分值。无需第三方变量完成值的交换,方便又简洁。

c 复制代码
function valReplace() {
        let x = 1;
        let y = 2;


        // 优化前
        // let temp = x;
        // x = y;
        // y = temp;

        // 利用 ES6 解构优化
        [x, y] = [y, x]
        console.log("x:", x, "y:", y); //x: 2 y: 1
}
c 复制代码
function allocated() {
        // 变量应用
        let num1, num2;
        // 传统写法
        num1 = 10;
        num2 = 100;
        // 使用解构语法在一行中分配多个值
        [num1, num2] = [10, 100];

        // 对象应用
        let student = {
            name: "Matt",
            age: 29,
        };
        // 传统写法
        let name = student.name;
        let age = student.age;
        // 解构语法赋值
        let {
            name,
            age
        } = student;
}

2.4 将任何值转换为布尔值

双叹号运算符是将其他类型值转化为布尔值。

c 复制代码
function typeCast() {
        // 使用 Boolean 包装类
        Boolean(0)
        Boolean([])
        Boolean("")
        Boolean({})

        // 在 JavaScript 中,你可以使用 !! 在 JS 中将任何内容转换为布尔值
        !!true // true
        !!2 // true
        !![] // true
        !!"Test" // true
        !!false // false
        !!0 // false
        !!"" // false
 }

2.5 数组组合合并

使用展开运算符可快速实现数组得到展开合并,快速高效。

c 复制代码
function arrConcat() {
        const nums1 = [1, 2, 3];
        const nums2 = [4, 5, 6];
        // concat 方法
        let newArray = nums1.concat(nums2);
        // 使用扩展运算符组合两个数组
        newArray = [...nums1, ...nums2];

        // 代替将值推送到数组
        let numbers = [1, 2, 3];
        // push 方法追加内容
        numbers.push(4);
        numbers.push(5);
        // 利用扩展运算符处理
        numbers = [...numbers, 4, 5];
}

2.6 为函数参数提供默认值

c 复制代码
function defaultArgs() {
        // 传统写法
        // function pickUp(fruit) {
        // 	if (fruit === undefined) {
        // 		console.log("I picked up a Banana");
        // 	} else {
        // 		console.log(`I picked up a ${fruit}`);
        // 	}
        // }

        // 参数提供默认值写法
        function pickUp(fruit = "Banana") {
            console.log(`I picked up a ${fruit}`)
        }

        pickUp("Mango"); // -> I picked up a Mango
        pickUp(); // -> I picked up a Banana
    }

2.7 将对象的值收集到数组中

c 复制代码
function objectVals() {
        const info = {
            name: "Matt",
            country: "Finland",
            age: 35
        };

        // 传统写法
        // let data = [];
        // for (let key in info) {
        //   data.push(info[key]);
        // }


        // 使用Object.values()将对象的所有值收集到一个新数组中
        const data = Object.values(info);
}

2.7 压缩多个条件

c 复制代码
function compCres() {
        const num = 1;

        // 传统的通过长 || 检查多个条件链
        // if(num == 1 || num == 2 || num == 3){
        //   console.log("Yay");
        // }

        // 使用 includes() 方法压缩条件链
        if ([1, 2, 3].includes(num)) {
            console.log("Yay");
        }
}

指数运算符

c 复制代码
function exponent() {
        // 求幂的传统写法使用 Math.pow()
        Math.pow(4, 2); // 16
        Math.pow(2, 3); // 8
        // ** 指数运算符写法
        4 ** 2 // 16
        2 ** 3 // 8


        // 向下取整传统写法 Math.floor()
        Math.floor(5.25) // -> 5.0
            // ~~  Math.floor()简写运算符
            ~~5.25 // -> 5.0
}

三、

3.1 模块化

  • 后端
  • NodeJs => CommonJS规范
  • 客户端
    • "CommonJS" => AMD规范

    • AMD:Asynchronous Module Definition 异步模块定义

      • define(moduleName,[module],factory); 定义模块
      • require([module],callback); 引入模块
      • RequireJS是对AMD规范的实现
    • CMD规范:阿里贡献模块化

      • Common Module Definition 通用模块定义
      • define(function(require,exports,module){...}) 定义模块(模块主入)

      seajs.use([module路径],function(moduleA,moduleB,moduleC){...}) 使用模块

      与 CommonJS 、AMD规范本质上的不同:CMD规范遵循依赖就近、按需加载,而前两者依赖前置

ES官方权威 => ES6模块化

Asynchronous Module Definition 异步模块定义

import module from '模块路径'; 导入模块

export module; 导出模块

区别:

  1. commonjs 模块输出的是一个值的拷贝,ES6模块输出的是值得引用
  2. commonjs模块是在运行时加载,es6模块(本身就是模块,只不过浏览器不支持,需要webpack环境编译)是在编译时加载

3.2 ES6新特性参考

相关推荐
长风清留扬4 分钟前
小程序毕业设计-音乐播放器+源码(可播放)下载即用
javascript·小程序·毕业设计·课程设计·毕设·音乐播放器
web1478621072318 分钟前
C# .Net Web 路由相关配置
前端·c#·.net
m0_7482478019 分钟前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
飞的肖22 分钟前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
青灯文案129 分钟前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
m0_7482548834 分钟前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl
ZJ_.1 小时前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
GIS开发特训营1 小时前
Vue零基础教程|从前端框架到GIS开发系列课程(七)响应式系统介绍
前端·vue.js·前端框架·gis开发·webgis·三维gis
Cachel wood1 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
学代码的小前端1 小时前
0基础学前端-----CSS DAY9
前端·css