2021-9-19
promise
Promise
对象的状态改变,只有两种可能:从pending
变为fulfilled
和从pending
变为rejected
。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。
通过promise实现图片懒加载
定义一个flag来确地图片是否加载完毕。
new Promise((resolve, reject) => { const image = new Image(); image.src = '图片的真实地址' // 图片加载成功 image.onload = () => { // 传出true表示图片加载完毕 resolve(true) } // image.onerror = () => { reject(false); }; }) // 外部接收到flag来做相应的处理。
返回一个异步操作,promise状态由谁决定
由后者决定
// 该例的状态由p1决定。 const p1 = new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('fail')), 3000) }) const p2 = new Promise(function (resolve, reject) { setTimeout(() => resolve(p1), 1000) }) p2 .then(result => console.log(result)) .catch(error => console.log(error))
Promise一些静态方法
all
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
参数必须是具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
该方法如果传入的promise实例都被resolve后才会将状态改变为fulfilled,只要有一个实例被reject后,他就被rejected,然后返回第一个被reject的实例。
race
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
如果传入的promise实例,有一个状态改变,那么promise.race的状态也随之改变,这个就好像赛跑一样,那一个promise的实例的状态先改变,promise.race的实例也随之改变。
该方法的作用是控制网络加载时长,如果到时见还没有加载完毕,就将他的状态变为rejected
const p = Promise.race([ fetch('/resource-that-may-take-a-while'), new Promise(function (resolve, reject) { setTimeout(() => reject(new Error('request timeout')), 5000) }) ]); p .then(console.log) .catch(console.error);
allSettled
用来确定一组异步操作是否都结束了(不管成功或失败)。
一旦发生状态变更,状态总是
fulfilled
,不会变成rejected
。
then方法接收的参数与promise实例传入的顺序相对应。是promise的实例改变状态传入的参数。
- 成功时: {status:‘fulfilled’, value:成功时传入的参数}
- 失败时: {status:‘rejected’, reason: 失败时传入的参数}
any
方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
该方法与all方法对应。
只要参数实例有一个变成
fulfilled
状态,包装实例就会变成fulfilled
状态;如果所有参数实例都变成rejected
状态,包装实例就会变成rejected
状态。
手写promise
建议看一下b站视频
简单的promise实现后,为什么异步任务不能准确执行呢?因为异步后,他的状态还没有从pending改变
怎么解决上述问题?当调用then方法的时候,当状态还是pending时,我们需要将回调函数传入各自的事件数组中(fulfilledArr, rejectedArr)。然后当异步调用resolve或者reject函数后,我们再调用相应的事件数组中的函数。 这里看是逻辑很奇怪,如果我们为调用then方法,那么事件数组中将没有事件,不会被调用,如果调用了then方法,那么如果是异步执行,我们将在resolve或者reject函数中执行传入的回调函数。
2021-9-20
html 的标签有哪些?(说的越多越好)
块级元素
若不设置宽度和高度 ,则宽度默认为父级元素的宽度(100%),高度根据内容大小自动填充。
常见的块级元素: div, p, form, table, hr, h1-6, dl, dt, dd(定义列表、列表中的项目、列表中项目的描述), ol, ul, li。
行内元素
行内元素只能容纳文本或者其他行内元素(a特殊,链接中不可再放链接),不可在其中嵌套其他块级元素
可以设置水平方向的padding和margin。并且可以设置垂直方向上的padding。
常见的行内元素:a, b, em, i, span, strong。
行内块元素
img, input。
空标签:
<br />、<hr />、 <img />、 <input />、<area />、 <base />、 <link />、 <meta />。
html 公共属性有哪些?还有自定义属性?
基本属性
class: 定义类规则或样式规则 id: 定义元素的唯一标识 style: 定义元素的样式声明。
但是下面这些元素不拥有基本属性style,但是可以通过id,style获取:
- html、head 文档和头部基本结构
- title 网页标题
- base 网页基准信息
- meta 网页元信息
- param 元素参数信息
- script、style 网页的脚本和样式
公共属性
class:为元素设置类标识,多个类名用空格分开,CSS和JavaScript的可通过类属性获取元素
contenteditable:指定元素内容是否可编辑。这个元素可以被继承。
contextmenu:自定义鼠标右键弹出菜单内容。这个属性浏览器不支持。
data- *:为元素增加自定义属性
dir:设置元素文本方向
draggable:设置元素是否可拖拽。选中元素,实现元素的拖拽。链接和图片默认是可以拖拽的。
dropzone:设置元素拖放类型:复制,移动,链接
hidden:表示一个元素是否与文档。样式上会导致元素不显示,但是不能用这个属性实现样式效果
id:元素id,文档内唯一
lang:元素内容的的语言
spellcheck:是否启动拼写和语法检查
style:行内css样式
tabindex:设置元素可以获得焦点,通过tab可以导航
title:元素相关的建议信息
translate:元素和子孙节点内容是否需要本地化
form 表单如何进行提交?
通过action属性提供提交的地址
普通提交时:必须指定提交的name和value。get提交:他上传的数据有限制,虽然url长度是没有限制的,但是服务器会自动屏蔽过长的url。
文件提交时:enctype="multipart/form-data", method=“post”。后端通过ctx.request.files拿到上传的文件。
enctype: application/x-www-form-urlencoded(默认)
"multipart/form-data"(文件上传)
“text/plain"
前端如何获取上传的文件:获取文件dom,然后dom.files获取文件数组。
前端如何将file转化为base64格式?
//file为一个文件对象。并且是Blob接口的对象。 function toBase64(file) { // 创建一个读取文件对象 let render = new FileReader() // 监听读取完成 render.onload = (e) => { // result为base64字符串 let base64Image = e.target.result; render = null;//内存回收 } render.readAsDataURL(file) }
介绍下 iframe,它有哪些优点和缺点
HTML内联框架元素表示嵌套的browsing context。它能够将另一个HTML页面嵌入到当前页面中。
处理过哪些 css 兼容性问题?
不同浏览器的默认样式存在差异,所以需要css初始化,可以通过css初始化库Normalize.css。
浏览器私有属性来对css属性进行兼容:对于书写顺序一定要注意,兼容性写法放到前面,把标准写法放到最后
- -moz-代表firefox浏览器私有属性
- -ms-代表IE浏览器私有属性
- -webkit-代表chrome、safari私有属性
- -o-代表opera私有属性
具体的兼容性问题:juejin.cn/post/684490…
详细说一下闭包和箭头函数,闭包和箭头函数分别解决了什么问题?
闭包
设置私有变量和方法
设置块级作用域。通过立即执行函数。
外部读取函数内部变量,让这些变量的值始终保持在内存中。
箭头函数
该函数没有自己的this。他的this是在函数编译的时候确定的,指向上一层函数中的this。
介绍一下 event loop,宏任务微任务
js是单线程的,同一时间只能做一件事情,可以通过event loop来提高执行效率。
js执行器:先执行主线程的代码。遇见异步任务,将他们分别放在event loop中,但是异步任务还可以细分为微任务与宏任务。当主线程空闲,就会去event loop中调用任务到主线程执行。然后不断重复此操作。
宏任务:
- script (可以理解为外层同步代码)
- setTimeout/setInterval
- UI rendering/UI事件
- postMessage、MessageChannel
- setImmediate、I/O(Node.js)
微任务:
- Promise.then()
- MutaionObserver
- Object.observe(已废弃;Proxy 对象替代)
- process.nextTick(Node.js)(这个Api是介于宏任务和微任务队列之间)
vue 异步加载的方式
组件的异步加载
- 通过Suspense
- 通过defineAsyncComponent()。该方法可以传入一个返回promise的函数,也可以传入一个对象。其中当和Suspense组件一起使用的时候,suspensible:false时,表示将使用自己的过度,错误等组件、如果设置为true,将忽略自身的过度,错误等组件,来使用suspense组件的过度组件。
- 路由的动态导入:通过weboackChunkName注释来指定异步块的包名称,如果指定的名称相同,我们将把他们打包到一个异步块。
- import()函数返回一个promise对象。
vue中的异步API
- nextTick: 当页面渲染完毕后,执行,返回一个promise对象。