[前端笔记022]Node.js之promise

前言

简介与安装

  • 运行在服务器上的JS,运行在V8引擎上;特点,单线程,异步,非阻塞
  • 安装,一是直接官网安装;二是使用安装工具安装,方便切换不同的版本,nvm工具
  • nvm的常用命令,nvm list:显示已安装的版本;nvm install 版本号/latest/lts:安装指定版本的node;配置nvm的镜像服务器来加速下载,nvm node_mirror https://npmmirror.com/mirrors/node/;nvm use 版本号:指定要使用的node版本
  • node.js与JavaScript的区别,node.js使用ECMAScript语法,没有DOM和BOM的部分。

同步与异步

  • 进程是厂房,线程是工人
  • 同步,一行行执行,某行执行慢,会出现阻塞情况;java,python等通过多线程解决问题,JavaScript通过异步解决问题
  • 异步:一段代码的执行不会影响到其他程序,比如在餐厅点完菜后去做别的事情;异步无法通过return 来设置返回值;特点,不会阻塞其他代码的执行,需要通过回调函数返回结果,回调函数指将函数作为函数参数传递。基于回调函数的异步的问题,代码可读性差,可调试性差,需要回调函数的结果作为下一个回调函数的输入时,造成回调地狱。
  • 解决方法,使用promise,代替回调函数返回结果。

promise

  • promise 特殊的存储数据的方式使得其可以用来存储异步调用的数据
  • 创建promise ,promise 的构造函数需要一个函数作为参数,也就是回调函数,const promis=new Promise(function(){})
  • 对象中的双中括号括起来的数据为隐含属性,不可访问和修改。
  • promise的构造函数的回调函数,会在创建promise 时调用,调用时会有两个参数传递进去,resolve()和reject()
  • 存储数据:通过resolve()和reject(),可以向promise 存储数据,结果显示在[[PromiseResult]]属性中,resolve()在执行正常时存储数据,reject()在执行错误时存储数据,通过函数存储数据就可以添加异步调用的数据
  • 读取数据:通过Promise的实例方法then来读取Promise中存储的数据;then需要两个回调函数作为参数,通过resolve存储的数据,会调用第一个函数返回,通过reject存储的或者出现异常时,会调用第二个函数返回。
  • Promise中维护了两个隐藏状态:PromiseResult,用来存储数据;PromiseState,用来记录Promise的状态(三种),pending(进行中),fulfilled(完成,通过resolve存储数据),rejected(拒绝,通过reject存储/出错了);State只能修改一次,修改后永远不会再变
  • Promise流程,当Promise创建时,PromiseState初始值为pending;当通过resolve存储数据时,PromiseState变成fulfilled,PromiseResult变成存储的数据;当通过rejected存储数据或出错时,PromiseState变成rejected,PromiseResult变成存储的数据或异常对象;
  • 当通过then读取数据时,相当于为Promise设置了回调函数,如果PromiseState变成fulfilled,则调用第一个回调函数返回数据;PromiseState变成rejected,则调用第二个回调函数返回数据
  • catch()用法和then类似,但只需要一个回调函数,catch()中的回调函数,只会在Promise被拒绝时才调用,catch()相当于then(null,reason=>{}),是一个专门处理Promise异常的方法
  • finally(),无论正常还是异常,总会执行的代码,但回调函数中不会接收数据
const promise=new Promise((resolve,reject)=>{
	resolve('haha')	
})
//实例方法读取
promise.then((result)=>{
	//第一个回调函数
},(reason)=>{
	//第二个回调函数
})
promise.catch((reason)=>{
	//处理异常
}

promise详解

  • promise中的then和catch都会返回一个新的promise,新的promise中会存储回调函数的返回值;finally也会返回一个promise,但其回调函数的返回值不会存储到新的promise中
  • 基于上述特点,可以使用then的链式调用防止回调地狱的产生;后边的方法then和catch读取上一步的执行结果,如果上一步的执行结果不是当前想要的结果,则跳过当前的方法。
  • promise出现异常时,而整个调用链中没有出现catch,则异常会向外抛出,所以调用链只需在最后加个catch来处理整个链的异常即可
  • 代码实例
const promise=new Promise((resolve,reject)=>{
	resolve('haha')	
})
//实例方法读取
promise
	.then(result=> result + 7)
	.then(result=> result + 8)
	.catch(result=> result + 7) //处理异常
}

promise静态方法

  • 直接通过类调用,而不是通过promise的实例调用
  • Promise.resolve(),创建一个立即完成的Promise,等价于new Promise((resolve,reject)=>{resolve()})
  • Promise.reject(),创建一个立即拒绝的Promise,等价于new Promise((resolve,reject)=>{reject()})
  • Promise.all(迭代对象),当获取到迭代对象中的所有返回值后返回,返回一个Promise对象可以直接接then等方法;迭代对象中有一个报错就返回错误
  • Promise.allSettled(迭代对象),同时返回多个Promise的执行结果,无论成功还是失败,settled指fulfilled和rejected。
  • Promise.race(迭代对象),返回执行最快的Promise,不考虑对错
  • Promise.any(迭代对象),返回执行最快的完成的Promise,全错的时候才报错
const promise=new Promise((resolve,reject)=>{
	resolve('haha')	
})
//输出['haha','haha','haha']
Promise.all([promise,promise,promise]).then(r => console.log(r))

微任务和宏任务

  • js的事件循环,有调用栈和任务队列
  • 任务队列又分为宏任务队列和微任务队列,大部分函数会在宏任务队列中排队,而promise的回调函数then、finally、catch会在微任务队列中排队
  • 执行的整个流程是,先执行调用栈的代码,再执行微任务队列中的所有任务,再执行宏任务队列中的所有任务

async和await

  • async,通过async可以创建一个异步函数,异步函数的返回值会自动封装到一个promise中,async function fn(){return 10}
  • await,通过await去调用异步函数时,会暂停代码的运行,直到异步代码执行有结果时,才将结果返回,直接获取到promise中的数据,不需要再使用then。await只能在async声明的异步函数中或者es模块的顶级作用域中使用(script标签type为moudle或在.mjs文件中)
  • await阻塞的只是异步函数内部的代码,不会影响外部代码
  • 通过await调用异步代码时,需要通过try-catch来处理异常
  • 如果async声明的函数中没有出现await,那么里面就会依次执行
  • await前面的和当前的函数执行完毕后,后面的函数会被放入微任务队列,
  • 立即执行函数中使用await,(async ()=>{ await log(hh)})()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值