一句话,它是 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
,仅此而已。
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
空值合并操作符(??)是一个逻辑操作符,当左侧的操作数为null或者undefined时,返回其右侧操作数,否则返回左侧操作数。
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
}
可选链:Optional Chaining Operator 可选链操作符是一个新的js api,它允许读取一个被连接对象的深层次的属性的值而无需明确校验链条上每一个引用的有效性。
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,如果不是,则继续往下运算。
使用解构从数组中拆分值。无需第三方变量完成值的交换,方便又简洁。
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
}
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;
}
双叹号运算符是将其他类型值转化为布尔值。
function typeCast() {
// 使用 Boolean 包装类
Boolean(0)
Boolean([])
Boolean("")
Boolean({})
// 在 JavaScript 中,你可以使用 !! 在 JS 中将任何内容转换为布尔值
!!true // true
!!2 // true
!![] // true
!!"Test" // true
!!false // false
!!0 // false
!!"" // false
}
使用展开运算符可快速实现数组得到展开合并,快速高效。
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];
}
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
}
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);
}
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");
}
}
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
}
“CommonJS” => AMD规范
AMD:Asynchronous Module Definition 异步模块定义
CMD规范:阿里贡献模块化
seajs.use([module路径],function(moduleA,moduleB,moduleC){…}) 使用模块
与 CommonJS 、AMD规范本质上的不同:CMD规范遵循依赖就近、按需加载,而前两者依赖前置
ES官方权威 => ES6模块化
Asynchronous Module Definition 异步模块定义
import module from ‘模块路径’; 导入模块
export module; 导出模块
区别: