import
关键字向外共享模块成员使用 export
关键字
注意:要想使用ES6模块化规范
必须在 package.json
的根节点中添加 "type": "module"
节点
默认导出的语法: export default 默认导出的成员
默认导入的语法: import 接收名称 from '模块标识符'
注意:默认导出只能导出一次
const money = 1000000
const userName = 'Tricia'
const age = 22
const sayHi = () => {
console.log('hi')
}
// 注意:默认导出只能导出一次
export default {
money,
userName,
age,
sayHi
}
默认导入
// 导入核心模块
import fs from 'fs'
console.log(fs)
// 导入自定义模块
import a from './a.js'
console.log(a.userName)
a.sayHi()
按需导入导出
语法:
按需导出的语法: export const a = 10
按需导入的语法: import { a } from '模块标识符'
注意:
可以导出多次
导出的名字是什么,导入的名字必须也一样
// 按需导出
// 直接使用export
// 注意:
// 1. 可以导出多次
// 2. 导出的名字是什么,导入的名字必须也一样
export const money = 100000
export const userName = 'Tricia'
export const sayHi = () => {
console.log('hi~~~~~~~')
}
按需导入
导入的一定要加花括号
如果不想使用导出的名字 as
表示重命名
import { money, userName, sayHi as say } from "./a.js"; // as表示重命名
console.log(userName)
say()
console.log(money)
直接导入
// 注意: 不需要加from
import './xxx.js'
同步异步
同步(synchronous)
sync
按顺序进行
async
同时进行
console.log(1)
setTimeout(() => {
console.log(2)
setTimeout(() => {
console.log(3)
}, 0)
}, 0)
setTimeout(() => {
setTimeout(() => {
console.log(4)
}, 0)
console.log(5)
})
console.log(6)
// 结果:1 6 2 5 3 4
Event Loop 事件循环队列
JavaScript是单线程语言
单线程执行任务队列的问题:如果前一个任务非常耗时,则后续的任务就不得不一直等待。
为了防止某个耗时任务导致程序假死的问题,异步代码 由JavaScript 委托给宿主环境(node环境, 浏览器)进行等待执行
宿主环境
多线程的
setTimeout(() => {
console.log(0)
}, 0)
console.log(1)
console.log(2)
console.log(3)
console.log(4)
console.log(5)
事件循环图解
异步函数 和 回调函数
异步函数:
setTimeoutsetIntervalajaxfs.readFile
回调函数:
把一个函数当成参数传递, 将来特定的时机调用, 这个函数就叫回调函数一般什么时候会用到回调函数, 异步的时候 , 定时器, ajax (success, error)
console.log(1)
setTimeout(function() {
console.log(2)
setTimeout(function() {
console.log(4)
}, 1000)
console.log(5)
}, 1000)
console.log(3)
回调函数缺点:
阅读性差,回调不会立马执行、可维护性差,如果有大量嵌套,会有回调地狱!
promise
基本语法
创建
const p = new Promise((resolve, reject) => {
// promise内部一般可以封装一个异步 *** 作
// resolve, reject 是 promise 内部提供好给你的两个函数
// 成功调用 resolve
// 失败调用 reject
})
使用
p.then(res => { ... }) // 处理成功
.catch(res => { ... }) // 处理失败
promise的三个状态
pending: 等待 (进行中)fulfilled: 成功 (已完成), 调用了 resolve, promise的状态就会被标记成成功rejected: 失败 (拒绝), 调用了 reject, promise的状态就会被标记成失败
💡 一旦promise的状态发生变化, 状态就会被凝固(即 不会再改变它的状态)
promise使用// 模拟可以得到的薪资
// resolve函数: 调用resolve promise的状态会发生变化 pending -> fulfilled
// reject函数:调用reject promise的状态会发生变化 pending -> rejected
// 定义
const p = new Promise((resolve, reject) => {
setTimeout(() => {
// 随机数
const money = Math.floor(Math.random() * (20000 - 10000)) + 10000
console.log(money)
if (money >= 14000) {
resolve()
} else {
reject()
}
}, 3000)
})
// 调用
// 如果promise状态是pending 则都不执行
// 如果是fulfilled,.then()执行
// 如果是rejected,.catch()执行
p.then(() => {
console.log('目标达成')
}).catch(() => {
console.log('还要继续努力呀!!')
})
promise链式调用
如果有多个 promise 需要处理, 支持链式编程。
如果上一个 .then()
方法中返回了一个新的Promise 实例对象,则可以通过下一个 .then()
继续进行处理。
因此, .then()
方法是 Promise 支持链式调用的本质原因。
import fs from 'fs'
const read = (file) => {
return new Promise((resolve, reject) => {
fs.readFile(file, 'utf-8', (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
// 按照顺序读取 a,b,c,d四个文件
// 不想读c文件,直接删掉就好,便于维护
read('a.txt')
.then(data => {
console.log(data)
return read('b.txt')
})
.then(data => {
console.log(data)
return read('c.txt')
})
.then(data => {
console.log(data)
return read('d.txt')
})
.then(data => {
console.log(data)
})
.catch(err => {
console.log(err)
})
promise 解决回调地狱
const p1 = new Promise(function (resolve, reject) {
// promise 内部会封装一个异步的 *** 作
// resolve: 成功的时候, 需要调用
// reject: 失败的时候, 需要调用
fs.readFile('a.txt', 'utf8', (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
const p2 = new Promise(function (resolve, reject) {
fs.readFile('b.txt', 'utf8', (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
...
...
...
p1.then(res => {
console.log(res)
return p2
}).then(res => {
console.log(res)
return p3
}).then(res => {
console.log(res)
return p4
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
但是这个看起来也不简便,下面进行优化。
function read (filename) {
return new Promise(function (resolve, reject) {
fs.readFile(filename, 'utf8', (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
read('a.txt').then(res => {
console.log(res)
return read('b.txt')
}).then(res => {
console.log(res)
return read('c.txt')
}).then(res => {
console.log(res)
return read('d.txt')
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
💡 在 Promise 的链式 *** 作中如果发生了错误,可以使用 .catch () 方法进行捕获和处理
Promise 的常用静态方法
Promise.all([ promise1, promise2, ... ]).then( ... )
Promise.all() 方法会发起并行的 Promise 异步 *** 作,等所有的异步 *** 作全部结束后才会执行下一步的 .then *** 作(等待机制)
Promise.race([ promise1, promise2, ... ]).then( .... )
Promise.race() 方法会发起并行的 Promise 异步 *** 作,只要任何一个异步 *** 作完成,就立即执行下一步的 .then *** 作(赛跑机制)
async 和 awaitasync 和 await 是一对关键字.必须同时使用
asyncasync用于修饰一个函数, 表示一个函数是异步的.
如果async函数内没有await, 那么async没有意义的, 全是同步的内容
只有遇到了await开始往下, 才是异步的开始。
awaitawait 要用在 async 函数中。
await 后面一般会跟一个promise对象, await会阻塞async函数的执行,直到等到 promise成功的结果(resolve的结果)
await 只会等待 promise 成功的结果, 如果失败了会报错, 需要 try catch.
import fs from 'then-fs'
async function read() {
const data1 = await fs.readFile('a.txt', 'utf-8')
console.log(data1)
const data2 = await fs.readFile('b.txt', 'utf-8')
console.log(data2)
const data3 = await fs.readFile('c.txt', 'utf-8')
console.log(data3)
const data4 = await fs.readFile('d.txt', 'utf-8')
console.log(data4)
}
read()
// aaaa bbbb cccc dddd
简单的测试一下~ // await之前的代码是同步的,await之后的代码是异步的
async function fn() {
console.log('嘿嘿')
const res = await fn2()
console.log(res)
}
async function fn2() {
await 1
console.log('嘎嘎')
return 100
}
fn()
console.log(222)
// 嘿嘿 222 嘎嘎 100
宏任务 微任务 宏任务: 主代码块, 定时器, 延时器的代码内容等都属于宏任务, 上一个宏任务执行完, 才会考虑执行下一个宏任务
微任务:当前宏任务执行完,在下一个宏任务开始之前需要执行的任务, promise 的 .then .catch 中的代码都属于微任务
注意点:
js 主线程遇到异步的内容, 交给浏览器去等待, 不会阻塞主线程一定是满足条件后的任务, 才会被添加到任务队列 简单测试一下~setTimeout(() => {
console.log(1);
}, 0);
new Promise((resolve, reject) => {
console.log(2);
resolve('p1')
new Promise((resolve, reject) => {
console.log(3)
setTimeout(() => {
resolve('setTimeout2')
console.log(4)
}, 0)
resolve('p2')
}).then(data => {
console.log(data)
})
setTimeout(() => {
resolve('setTimeout1')
console.log(5)
}, 0);
}).then(data => {
console.log(data)
})
console.log(6)
// 2 3 6 p2 p1 1 4 5
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)