js 分2中任务 同步 和 异步
异步任务 : 微任务和宏任务
多数异步任务都是宏任务 ,微任务 promise里的then 方法 和 MutationObserver
异步任务的精度问题 ;
宏任务 : 【1】【2】【3】【4】【5】 所有任务必须排队执行 ,会出现精度误差
| 【6】
微任务 : 【1】【2】【3】【4】【5】 需要排队 ,可以插队 ;
| 【6】
微任务和宏任务的执行顺序
【1 [微任务队列]】 【2[微任务队列]】 【3[微任务队列]】 。。。。
promise的周边方法 : 1.实例方法 2.静态方法 ;
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
fn(){ // 实例方法
console.log("fn")
}
static myfn(){ // 静态方法 ,不需要实例化
console.log("myfn")
}
}
let zhangsan = new Promise("张三",20);
zhangsan.fn();
Person.myfn();
一、实例方法
1.catch : 捕捉错误的
let p = new Promise((res,rej)=>{
res(111)
// rej("error");
})
// p.then(res=>{
// console.log(res);
// }).catch(err=>{
// console.log(err);
// })
p.then(res=>{
console.log(res);
return new Promise((res,rej)=>{
// res(222);
rej("error2");
})
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
2.finally : 代码执行完毕之后执行
let p = new Promise((res,rej)=>{
setTimeout(() => {
// res(111);
rej("err");
}, 1000);
})
p.then(res=>{
console.log(res);
},err=>{
console.log(err);
}).finally(()=>{
console.log("代码执行完毕后执行");
})
promise的静态方法
1.Promise.resolve(result): 创建一个成功状态的promise对象
let p = new Promise((resolve)=>{
resolve(111);
})
console.log(p);
let p = Promise.resolve(1111);
console.log(p);
class MyPromise{
static resolve(result){
return new Promise(resolve=>{
resolve(result);
})
}
}
let p = MyPromise.resolve("hello");
console.log(p);
2.Promise.reject:创建一个失败状态的promise对象
let p = Promise.reject("error");
// console.log(p);
p.catch(err=>{
console.log(err);
})
3.Promise.race : 优先获取多个promise对象里执行最快的结果值 ;
let p1 = new Promise((res,reje)=>{
setTimeout(() => {
res(111)
}, 2000);
})
let p2 = new Promise((res,reje)=>{
setTimeout(() => {
res(222)
// reje("error222")
}, 1000);
})
let p3 = new Promise((res,reje)=>{
setTimeout(() => {
res(333)
}, 3000);
})
Promise.race([p1,p2,p3]).then(res=>{
console.log(res)
},err=>{
console.log(err);
})
class MyPromise{
static race(arr){
return new Promise((resolve,reject)=>{
arr.forEach(item=>{
// item.then(res=>{
// resolve(res);
// },err=>{
// reject(err);
// })
item.then(resolve,reject);
})
})
}
}
let res = MyPromise.race([p1,p2,p3]).then(res=>{
console.log(res)
},err=>{
console.log(err);
})
document.onclick = function(e){
console.log(e);
}
document.onclick = console.log;
let p = Promise.resolve(111);
p.then(console.log);
4.Promise.all 方法 : 执行所有的promise对象 然后获取到所有的结果值 ; 所有promise对象必须是成功才能获取结果值;
let p1 = new Promise((res, reje) => {
setTimeout(() => {
res(111)
}, 2000);
})
let p2 = new Promise((res, reje) => {
setTimeout(() => {
res(222)
}, 1000);
})
let p3 = new Promise((res, reje) => {
setTimeout(() => {
res(333)
// reje("err333")
}, 3000);
})
Promise.all([p1,p2,p3]).then(res=>{
console.log(res);
},err=>{
console.log(err);
})
async 和 await 是 ES8更新的语法糖 是 then的语法糖 ;
then的调用改写成 async 和await
async 是异步的意思,await则可以理解为 async wait。所以可以理解async就是用来声明一个异步方法,而 await是用来等待异步方法执行
function fn1() {
return new Promise(res => {
setTimeout(() => {
console.log(111);
res(111)
}, 1000);
})
}
function fn2() {
return new Promise(res => {
setTimeout(() => {
console.log(222);
res(222)
}, 1000);
})
}
function fn3() {
return new Promise((res, rej) => {
setTimeout(() => {
console.log(3333);
rej("err333")
}, 1000);
})
}
fn1().then(res=>{
console.log(res);
return fn2();
}).then(res=>{
console.log(res)
return fn3();
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
需要声明一个 async 函数
async function fn() {
try {
let res1 = await fn1(); // res1 等同于 then里的res的值;
console.log(res1)
let res2 = await fn2();
console.log(res2)
let res3 = await fn3();
console.log(res3)
} catch (err) {
console.log(err);
}
}
fn();
注意点:
1. await 一定要出现在 async 函数里
await不能出现在嵌套函数里
function fn(){
document.onclick = async ()=>{
let res = await fn1();
console.log(res);
}
}
- await 后面的内容一定是一个 promise 对象 ,如果是普通值 会自动通过 Promise.resolve 包裹;
async function fn() {
let res = await 111;
// Promise.resolve(111);
console.log(res);
}
fn();
3.await 只会等待一个async里的异步内容
function fn1() {
return new Promise(res => {
setTimeout(() => {
console.log(111);
res(111)
}, 1000);
})
}
function fn2() {
return new Promise(res => {
setTimeout(() => {
console.log(222);
res(222)
}, 1000);
})
}
function fn3() {
return new Promise((res, rej) => {
setTimeout(() => {
console.log(3333);
res(3333);
// rej("err333")
}, 1000);
})
}
let arr = [fn1,fn2,fn3];
async function myfn(){
// arr.forEach(async item=>{
// let res = await item();
// console.log(res);
// })
for(let i=0;i<arr.length;i++){
let res = await arr[i]();
console.log(res);
}
}
myfn();
- async 异步还是同步问题 ; async 是同步 ,await之后是 异步 微任务;
async function fn(){
await 222;
console.log(111);
}
fn();
console.log(222);
- async函数的返还值
async 返还值和then的返还值一致 ;
1.没有返还 ,返还成功状态的promise对象 结果值 undefined
2.返还普通值 返还成功状态的promise对象 结果值 就是这个普通值
3.返还一个promise 对象 会直接把这个对象返还
4.抛出一个错误 ,返还一个 错误状态的promise对象 ;
async function fn(){
// return 111;
// return Promise.resolve("hello");
throw new Error("error");
}
let res = fn();
console.log(res);
nodejs 是什么?
nodejs 是js ,是一门后端语言;类似java php ...
js 运行在哪里 ? 运行在客户端 那么就是js ,运行在服务端就是 nodejs ;
console.log("hello");
nodejs 和 js 环境区别 ? node 端没有window dom 相关对象...
先进入node执行环境 ,直接输入node 。 这个环境叫 repl 交互式解释器 类似浏览器的 console
为什么要学习 nodejs ?
1.项目环境需要使用nodejs
2.前后端分离 ,mock 假数据
- 为前后端交互做准备
nodejs中的模块化 模块 : nodejs中模块 ? 1.内置模块(nodejs已经安装好的 ,fs 、http、querystring...) 2.自定义模块 (自己写的模块) 3.第三方模块 (别人写的模块)
自定义模块需要遵循 commonjs规范 。 一、文件模块,文件作为模块 文件和目录 1.导入 : require(路径) 2.导出: module.exports 或者 exports 独立的命名空间
let res = require("./a.js"); // 引入a模块
let {a} = require("./a.js");
console.log(a);
let mymodule = {
exports:{
a:10 // 该变这个值才会导出
}
}
let myexports = mymodule.exports;
// myexports.a = 20;
myexports = {
a:20
}
console.log(mymodule.exports);
nodejs 多数情况下 模块都有相互依赖关系 ,那么一个文件不足以满足需求;
let res = require("./mymodule/index.js");
如果单入口文件名称叫 index.js 那么可以省略掉index.js路径
目录模块的 ./ 不能省略
let res = require("./mymodule");
console.log(res);
修改目录模块中的单入口文件名称
默认单入口会指向 index.js
-
需要再目录模块中新建一个文件叫 package.json
新建package.json ,通过命令 npm init 或者 npm init -y
模块的名称不支持 中文 。
-
修改/添加 pageage.json里的main 字段;
特殊的目录模块 :node_modules 所有的模块都会放在一个叫node_modules的目录里
1.没有 ./ 2.node_modules目录省略了;
node_modules的模块一般都是第三方模块;
node_modules 会向上查找;
node_modules会找到全局的node_modules目录里 ;
可以通过指令 npm root -g 查看
let res = require("mymodulea");
let res2 = require("mymoduleb");
console.log(res,res2);
总结: 模块 commonjs规范: 1.内置模块
-
自定义模块
文件模块
目录模块 : package.json 可以修改单入口 npm init
3.特殊目录模块 (第三方模块)
会在node_modules里 会向上进行查找;
http 模块 内置模块,不需要安装,创建http服务的;
const http = require("http");
const server = http.createServer((req,res)=>{
// req : request ,和请求有关的内容
// res : response ,和服务器返还有关的内容
res.write("hello11111"); // 给浏览器返还内容
res.end(); // 告诉浏览器返还结束了;
})
server.listen(8989);
设置服务器的端口
注意 :一个端口号只能启动一个服务;
任何地址 : 协议 : 域名 : 端口 地址
ipconfig 查看ip地址
修改了服务器里nodejs的内容 那么 nodejs 需要重启