记录10月23号一次的面试

新开一个 tag 主要用来记录,我这🥦🐔面试时没回答好的问题!

Promise 如何执行多个请求,请求失败如何继续执行

常用场景,多 image url 请求。

  • Promise.allSettled() 不管是rejected还是fulfilled状态都会等到最后一个请求结束,才算真的结束。
  • Promise.any() 方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态,与数组some函数的概念有点相似。该方法目前是一个第三阶段的提案。
Promise:异步解决方案
    - 特点:
      - Primise对象状态不受外界影响(三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败))。
      - 状态只能改变一次。

    - 缺点:
      - 无法取消Promise
      - 一旦新建会立即执行
      - 不设置回调函数,Promise内部抛出的错误,不会反应到外部
      - 异步执行结束时间未知

    resolve或reject并不会终结 Promise 的参数函数的执行。配合return才可以 (return resolve())

    Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误
new Promise((resolve, reject) => { resolve(1); console.log(2); }).then(r => { console.log(r); }); // 2 // 1

Angular的优势是什么

大佬们给出了答案

Angular 过时了吗?

文中提到:Angular 升级稳定、标准统一、长期维护成本低、协作方便,不需要频繁重构

确实angular2之后angular-cli提供了一个大生态,TypeScript、Rxjs、animation、http等等,像animation这种库Vue一般需要额外引入,也是为了体积小,以便给予用户高度自定义。相反angular集成到了CLI内部,这既能说优点也能说缺点。从ng2到ng9的变化并不大,angular内部已经形成标准,因此长期维护成本不高。
如果你追求的是绝对的自由,那你使用 Angular 的时候感受到的一定会是各种限制。
每个框架都有自己的使用场景,砂锅适合炖汤,平底锅适合煎蛋,只是人们的喜好不同罢了。

请求方式 options 有什么作用

MDN:HTTP 的 OPTIONS 方法 用于获取目的资源所支持的通信选项。客户端可以对特定的 URL 使用 OPTIONS 方法,也可以对整站(通过将 URL 设置为“*”)使用该方法。

在跨域的情况下,在浏览器发起”复杂请求”时主动发起的。跨域共享标准规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。、

简单请求与复杂请求
某些请求不会触发 CORS 预检请求,这样的请求一般称为”简单请求”,而会触发预检的请求则称为”复杂请求”。

简单请求

  • 请求方法为GET、HEAD、POST时发的请求
  • 人为设置了规范集合之内的首部字段,如Accept/Accept-Language/Content-Language/Content-Type/DPR/Downlink/Save-Data/Viewport-Width/Width
  • Content-Type 的值仅限于下列三者之一,即application/x-www-form-urlencoded、multipart/form-data、text/plain
  • 请求中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器;
  • 请求中没有使用 ReadableStream 对象。

复杂请求

  • 使用了下面任一 HTTP 方法,PUT/DELETE/CONNECT/OPTIONS/TRACE/PATCH
  • 人为设置了以下集合之外首部字段,即简单请求外的字段
  • Content-Type 的值不属于下列之一,即application/x-www-form-urlencoded、multipart/form-data、text/plain

options 请求就是预检请求,可用于检测服务器允许的 http 方法。当发起跨域请求时,由于安全原因,触发一定条件时浏览器会在正式请求之前自动先发起 OPTIONS 请求,即 CORS 预检请求,服务器若接受该跨域请求,浏览器才继续发起正式请求。

options 优化
当我们发起跨域请求时,如果是简单请求,那么我们只会发出一次请求,但是如果是复杂请求则先发出 options 请求,用于确认目标资源是否支持跨域,然后浏览器会根据服务端响应的 header 自动处理剩余的请求,如果响应支持跨域,则继续发出正常请求,如果不支持,则在控制台显示错误。

由此可见,当触发预检时,跨域请求便会发送 2 次请求,既增加了请求数,也延迟了请求真正发起的时间,严重影响性能。
  - 发出简单请求。
  - 服务器端设置 Access-Control-Max-Age 字段,那么当第一次请求该URL时会发出 OPTIONS 请求,浏览器会根据返回的 Access-Control-Max-Age 字段缓存该请求的OPTIONS预检请求的响应结果(具体缓存时间还取决于浏览器的支持的默认最大值,取两者最小值,一般为 10分钟)。在缓存有效期内,该资源的请求(URL和header字段都相同的情况下)不会再触发预检。(chrome 打开控制台可以看到,当服务器响应 Access-Control-Max-Age 时只有第一次请求会有预检,后面不会了。注意要开启缓存,去掉 disable cache 勾选。)

什么是委托

委托行为意味着某些对象(XYZ)在找不到属性或者方法引用时会把这个请求委托给另一个对象(Task)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14

let Task = {
setID: function(ID) { this.id = ID; },
outputID: function() { console.log( this.id ); }
}

// 让XYZ委托Task ==> XYZ.__proto__ = Task;
XYZ = Object.create( Task );

XYZ.prepareTask = function(ID,Label) {
this.setID( ID );
this.label = Label;
};

XYZ 通过 Object.create(..) 创建,它的 [[Prototype]] 委托了 Task 对象。
某种意义上讲 XYZ 对象没有某个属性的情况下,会去借用 Task 对象上的同名属性。