1. 对 async,await 的理解, 内部原理?
1async--- 声明一个异步函数:
自动将常规函数转换成 promise, 返回值也是一个 promise 对象,
只有 async 函数内部的异步操作执行完, 才会执行 then 方法指定的回调函数, 内部可以使用 await;
2await-- 暂停异步的功能执行:
放在 promise 调用之前, await 强制其他代码等待, 直到 promise 完成并返回结果,
只能与 promise 一起使用, 不适用于回调, 只能在 async 函数内部使用.
下面介绍下使用场景:
a. 同时发出三个互不依赖的请求,
不建议使用
- async/awaitasync function getABC() {
- let A= await getValueA();//A needs 2 second
- let B= await getValueB();//B needs 2 second
- let C= await getValueC();//C needs 2 second
- return A*B*C;
- }
上图所示,
上面我们 A 需要 2s,B 需要 4s,C 需要 3s,
我们如上图所示发请求, 就存在彼此依赖的关系, c 等 b 执行完, b 等 a 执行完,
从开始到结束需要 (2+3+4)9s.
此时我们需要用 Promise.all() 将异步调用并行执行,
而不是一个接一个执行,
如下所示:
- async function getABC() {
- let results = await Promise.all([getValueA,getValueB,getValueC]);
- return results.reduce((total,value)=>total*value)
- }
这样将会节省我们不少的时间, 从原来的的 9s 缩减到 4s.
b. 一个需要验证码提交表单的页面请求,
此时使用 async/await 会更好常规代码
- const call1Promise = fetch('/#1...');
- call1Promise.then(response=>response.JSON())
- .then(JSON=>{
- // 验证码返回后的后续操作
- const call2Promise = fetch('/#2...');
- return call2Promise;
- })
- .then(response=>response.JSON())
- .then(JSON=>{
- console.log(JSON.respCode);
- })
- .catch(err=>{
- console.log(err);
- })
用 Async/Await 的方式将逻辑分装在一个 async 函数里,
这样就可以直接对 promise 使用 await 了, 也就规避了写 then 回调.
最后我们调用这个 async 函数, 然后按照普通的方式使用返回的 promise.
美哉!
- async function postForm(){
- try{
- // 验证码是否通过, 拿到返回的 JSON
- const response1 = await fetch('/#1...');
- const json1 = await response1.JSON();
- let json2;
- // 对第一个请求的返回数据进行判断
- // 满足条件则请求第二个接口并返回数据
- if(json1.respCode===200){
- const response2 = await fetch('/#2...');
- json2 = await response2.JSON();
- }
- return json2;
- }catch(e){
- console.log(e);
- }
- }
简单的模拟场景
2. 介绍下 Promise, 内部实现?
promise 从字面上理解就是承诺, 即未来完成的事儿.
从语法上来看, 它是一个对象,
从它这里可以获取下一步操作的消息,
而 promise 对象的状态不受外部影响.
相关代码如下:
- const PENDING = 'pending'; // 初始状态
- const FULFILLED = 'fulfilled'; // 成功状态
- const REJECTED = 'rejected'; // 失败状态
- function Promise(extutor){
- let self = this;
- self.status = PENDING; // 设置状态
- // 存放成功回调的数组
- self.onResolveCallbacks = [];
- // 存放失败回调的数组
- self.onRejectedCallbacks = [];
- function resolve(value){
- if(self.status === PENDING){
- self.status = FULFILLED;
- self.value = value;
- self.onResolveCallbacks.forEach(cb => cd(self.value))
- }
- }
- function reject(reason){
- if(self.status === PENDING){
- self.status = REJECTED;
- self.value = reason;
- self.onRejectCallbacks.forEach(cb => cd(self.value))
- }
- }
- try{
- excutor(resolve, reject)
- } catch(e) {
- reject(e)
- }
- }
3.Http 请求中的 keep-alive 有了解吗?
在 http 早期, 每个 http 请求都要求打开一个 tpc socket 连接,
并且使用一次之后就断开这个 tcp 连接.
使用 keep-alive 可以改善这种状态,
即在一次 TCP 连接中可以持续发送多份数据而不会断开连接.
通过使用 keep-alive 机制, 可以减少 tcp 连接建立次数,
也意味着可以减少 TIME_WAIT 状态连接,
以此提高性能和提高 http 服务器的吞吐率
(更少的 tcp 连接意味着更少的系统内核调用, socket 的 accept() 和 close() 调用).
但是, keep-alive 并不是免费的午餐, 长时间的 tcp 连接容易导致系统资源无效占用.
配置不当的 keep-alive, 有时比重复利用连接带来的损失还更大.
所以, 正确地设置 keep-alive timeout 时间非常重要.
4.http 中的状态码 302 代表的是什么意思?
302 重定向表示临时性转移 (Temporarily Moved ),
当一个网页 URL 需要短期变化时使用.
顺便提一嘴 301301 重定向 / 跳转一般,
表示本网页永久性转移到另一个地址.
301 是永久性转移 (Permanently Moved),SEO 常用的招式,
会把旧页面的 PR 等信息转移到新页面 301 重定向与 302 重定向的区别
301 重定向是永久的重定向,
搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址.
302 重定向是临时的重定向,
搜索引擎会抓取新的内容而保留旧的网址.
因为服务器返回 302 代码,
搜索引擎认为新的网址只是暂时的.
5. 请描述 utf-8 和 unicode 的区别?
Unicode 是「字符集」UTF-8 是「编码规则」Unicode 是一套复杂的字符编码标准,
简单来说就是将人类使用的每个所谓字符与一个非负整数对应,
并且保证不同的字符对应的整数一定不同.
UTF-8 是这个整数的编码方式, 用 1 到 4 字节来表达一个整数.
关系: UTF-8 是 Unicode 的实现方式之一,
它规定了字符如何在计算机中存储, 传输等.
来源: http://www.jianshu.com/p/d1f6688094cb