进程和线程
(工厂) 进程: 程序运行的环境
(工人) 线程: 实际进行运算的东西
同步: 自上而下执行代码,前面的执行完了,后面的才会执行,同步的代码会出现阻塞的情况。
异步:不会阻塞代码,但是需要函数来返回结果
异步带来的问题
- 代码的可读性差
- 可调式性差
-解决问题:
- 需要一个东西,可以代替回调函数来给我们返回结果
-promise
Promise ----是一个可以用来存储数据的对象,可以用来存储异步调用的数据
Promise
- 最大特点: 链式调用,解决异步问题
- Promise可以帮助我们解决异步中的回调函数的问题
- Promise 就是一个用来存储数据的容器
它拥有一套特殊的存取数据的方式,这个方式使得它里边可以存储异步调用的结果
Const promise = new Promise((resolve,reject)=>{ //resolve 和 reject 是两个函数,通过这两个函数可以向 Promise 中存储数据 //resolve 在执行正常时存储数据,reject 在执行错误时存储数据 Reject(“哈哈”); }) Console.log(promise); |
then
- 从 Promise 中读取数据
- 可以通过 promise 的实例方法 then 来读取 promise 中存储的数据
- then 需要两个回调函数作为参数,回调函数用来获取 promise 中的数据
- 通过 resolve 存储的数据,会调用第一个函数返回数据
可以在第一个函数中编写处理数据的代码
- 通过 reject 存储的数据或者出现异常时,会调用第二哥函数返回数据
可以在第二个函数中编写处理异常的代码
第一个函数返回的是 resolve 的数据
第二个函数返回的是 reject 的数据
catch()
用法和 then 类似,但是只需要一个回调函数作为参数,它是一个专门处理 Promise 异常的方法
- catch() 中的 回调函数只会在 Promise 被拒绝时才调用
- (catch() 中的回调函数返回的是 rejected 或者 报错 时的数据)
- catch() 相当于 then(null,reason=>{})
finally()
- 无论是正常存储数据还是处理异常了,finally 总会执行
- 但是 finally 的回调函数中不会接收到数据
- finally() 通常用来编写一些无论成功与否都要执行代码
Promise 中的 then (return new Promise() ),catch - 这三个方法都会返回一个新的 Promise
Promise 中存储的是回调函数的返回值
Finally ,finally 的返回值不会存储到 Promise中
JS 是线程的,它的运行是基于事件循环机制(event loop)
- 栈 ,一种数据解构,先进后出
- 调用栈 ,放的是要执行的代码,是正在执行的
- 队列 ,一种数据解构,先进先出
- (消息队列)任务队列 ,放的是将要执行的代码,是等候执行的,是待命的
执行过程是,调用栈的代码先执行,当调用栈空了,依次将正在排队的消息队列放进来到调用栈中,直到队列中的代码都执行完成。
微任务和宏任务
整个流程:
- 执行调用栈中的代码
- 执行微任务队列中的所有任务
- 执行宏任务队列中的所有任务
微任务包括,在 promise,resolve,catch,then 里面的代码就是微任务。
queueMicrotask() 用来向微任务队列中添加一个任务
async 和 await
加上 async 就相当于加了 Promise.resolve
加上 await 就相当于加了 Promise.then
Async
被它用来修饰就是异步函数
通过 async 可以来创建一个异步函数,异步函数的返回值会自动封装到一个Promise 中返回
Async function fn11(){ Return 10; } 等价于下面这个 Function fn(){ Return Promise.resolve(10) } |
Await
当我们通过 await 去调用异步函数时,它会暂停代码的运行,直到异步代码执行有结果时,才会将结果返回。
在 async 声明的异步函数中可以使用 await 关键字来调用异步函数
注意:await只能用于 async 声明的异步函数中,或者 es模块的顶级作用域中
Await 阻塞的只是在 async 声明的函数中的,当前执行代码的后续一些代码,不会影响外部代码
CommonJS是Node.js中的模块化规范
引入模块
- 使用 require(“模块的路径”)函数来引入模块
- 引入自定义模块时,模块名要以 ./ 或者 ../ 开头
- 扩展名可以省略
Exports 本身是一个对象,改成别的相当于改变量,本身 exports这个对象是module的属性
//可以通过 exports 一个一个的导出值
exports.a = 10;
exports.b = {name:"猪八戒"};
exports.c = function fn(){console.log("hh");}
//也可以通过 module.exports 同时到处多个值
module.exports= {
a:"hh",
b:[1,3,5,7],
c:()=>{
console.log(111)
}
}