Minimal and Clean blog theme for Hugo

promise


promise

promise状态

  • pendding
  • fulfilled
  • rejected

转换

只能发生一次,且不可逆 未调resolve或reject时是pendding

静态方法

  • resolve
  • reject
  • all,全部fulfilled才resolve
  • race,第一个到settled状态的
  • allSettled,全部settled不管reject和resolve
  • any,第一个resolve状态的

await/async

  • await是相当于把下面的代码放到了then的回调里。
  • async是相当于将函数放到了promise的构造函数里,resolve()之前。
console.log(0);

async function fetchData() {
  console.log(1);
}

let a = await fetchData()
console.log(2);

上面的代码与下面的代码一样的效果。

console.log(0);

function fetchData() {
  return new Promise((resolve) => {
    console.log(1);
    resolve(); // 模拟异步操作的解决
  });
}

fetchData().then(() => {
  console.log(2);
});
Read more ⟶

React v18 新特性


并发渲染模式

  • ReactDOM.createRoot开启并发模式
  • useTransition并发更新
    • startTransition将更新标记为低优先级
  • useDeferredValue延迟响应的值
    • 也是被标记为低优先级
  • 优先级调度
    • 高优先级的任务可以打断低优先级
    • 比如input输入

自动批量更新

  • 原来只在合成时间中进行批处理,在promise、timeout、原生事件不批处理
  • 现在都自动批处理
  • 现在都会批处理,flushSync可以不批处理
Read more ⟶

authjs


import NextAuth from "next-auth"  
import GitHub from "next-auth/providers/github"  
  
export const { handlers, signIn, signOut, auth } = NextAuth({  
  providers: [  
    GitHub  
  ],  
  callbacks: {  
    authorized({ request, auth }) {  
      const { pathname } = request.nextUrl  
      if (pathname === "/middleware-example") return !!auth  
      return true  
    },  
    jwt({ token, trigger, session, user }) {  
      if (user) { // User is available during sign-in  
        token.id = user.id  
      }  
      if (trigger === "update") token.name = session.user.name  
      return token  
    },  
  },  
})

github登录后会走到signIn中

jwt中比较适合将一些用户角色之类的信息存到token

Read more ⟶

shadcn问题


启动项目时,报错 border-border 这个class找不到

解决方法

因为 同时存在 tailwind.config.ts 和 tailwind.config.js 文件,将 js 文件删除即可。

Read more ⟶

太想进步了


基础知识

算法

项目、亮点、难点

博客、社区

英语


不搞项目了

专心搞面试题,和进步套餐

Read more ⟶

vercel 和 github 模版


经常看到一些 github 库有一个一键部署到 vercel 按钮,它其实是一个 markdown 链接。

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Ftree%2Fcanary%2Fexamples%2Fhello-world)

github 可以将一个仓库设置为模版,就在仓库的 setting 页面,第一个 checkbox 就是。勾上以后,仓库的右上角就会有这个按钮,就可以用模版创建一个仓库了。

Read more ⟶

next-postgres-prisma


Vercel Postgres Demo with Prisma 使用这个模版点部署到 vercel ,会在 github 创建一个仓库。然后正常部署。

部署后,从github拉代码。然后需要把环境变量拉下来。Environment Variables (vercel.com)

安装 vercel cli pnpm i -g vercel Vercel CLI Overview

拉环境变量 vercel env pull ,然后就可以正常启动项目了。

Read more ⟶

面试题汇总


bable是什么,有什么作用

babel是一个ES6转码器,可以将ES6转化为ES5,兼容不支持ES6的平台

let var const的区别

  • let const 不会变量提升,而var可以
  • 相同作用域下,let const 不能重复声明,而var可以
  • const 声明一个只读常量,且必须有初始值,不可以变

举一些ES6String字符串类型做的常用升级优化

模板字符串 includes startsWith endWith repeat

你是一名经验丰富的前端工程师兼架构师。你现在在一家开发ERP系统的SaaS公司工作,现在需要你设计一个表单功能,需求如下:

  1. 表单基本功能:
    1. 基于mobx的响应式数据
    2. 基于元数据驱动
      1. 业务对象会通过元数据描述
      2. 业务对象的字段也通过元数据描述
    3. 基于布局模板渲染表单
      1. 布局模板可以针对某个业务对象设置不同的展示字段和布局
        1. 业务对象包含的字段信息来自于元数据
      2. 布局模板要区分查看态和编辑态
      3. 布局模板可以设置宽度高度顺序等外观效果
    4. 查看态
    5. 编辑态
      1. 可定制的初始化数据
      2. 基于元数据的保存校验
      3. 基于业务代码的保存校验
  2. ERP系统中会有大量的业务对象和表单。针对不同的业务对象,表单功能要是灵活的兼容性强的。
  3. SaaS服务又要针对不同的企业提供服务。针对同一业务对象,不同的企业可以在基础布局模板上进行自定义。 针对以上需求,使用React和Mobx进行架构设计,要包含技术方案,组件设计(包含主要参数),不需要具体的代码实现。
Read more ⟶

箭头函数


  • 箭头函数没有独立的 thisarguments 和 super 
  • 箭头函数不能用作构造函数。使用 new 调用它们会引发 TypeError

不能用作方法没有this

箭头函数表达式只能用于非方法函数,因为它们没有自己的 this。让我们看看将它们用作方法时会发生什么:

const obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c() {
    console.log(this.i, this);
  },
};

obj.b(); // 输出 undefined, Window { /* … */ }(或全局对象)
obj.c(); // 输出 10, Object { /* … */ }

由于类体具有 this 上下文,因此作为类字段的箭头函数会关闭类的 this 上下文,箭头函数体中的 this 将正确指向实例(对于静态字段来说是类本身)。但是,由于它是一个闭包,而不是函数本身的绑定,因此 this 的值不会根据执行上下文而改变。

class C {
  a = 1;
  autoBoundMethod = () => {
    console.log(this.a);
  };
}

const c = new C();
c.autoBoundMethod(); // 1
const { autoBoundMethod } = c;
autoBoundMethod(); // 1
// 如果这是普通方法,此时应该是 undefined

这两个例子的区别是,对象字面量中的箭头函数方法没有绑定this,类字段的箭头函数有this上下文。

Read more ⟶

了解TCP协议


TCP头的格式 ![[Pasted image 20240402201217.jpg]]

过程 ![[Pasted image 20240402202036.jpg]]

三次握手

  • 第一次握手:客户端发送给服务端一个SYN报文(synchronize,think nai zi)
  • 第二次握手:服务端发送给客户端一个SYN/ACK报文
  • 第三次握手:客户端回复一个ACK报文,握手完成。
  1. SYN:client 随机生成起始分组序列号 x ,并发送SYN分组,还有其他TCP表示和选项
  2. SYN ACK:server 将 x+1 ,生成随机序列号 y
  3. ACK:client 将 x + 1,y + 1,发送ACK分组,完成握手。

SYN与ACK都是报文中的flags字段,它是一个二进制数据 x+1与y+1都是作为报文中的 Acknowledge Number 字段发送的 序列号叫Sequence Number,为了解决数据包的顺序和重复请求

双方各进行了一次SYN和ACK,使彼此确认了对方可以正常接受和发送能力。 第一次,客户端发送能力正常 第二次,服务端接受能力正常,发送能力正常 第三次,客户端接受能力正常。

其中SYN和ACK都是报文中的标志位。除了标志位还有Sequence Number 序列号和Acknowledgmengt Number 确认号。

第一次握手是SYN和随机数序列号,第二次握手是SYN/ACK和随机数序列号还有确认号为客户端序列号+1,+1的目的是告诉对方自己已经收到。第三次握手,客户端也会确认收到序列号。

四次挥手

![[285729db06404505887b554c12d4c230~tplv-k3u1fbpfcp-zoom-in-crop-mark_1512_0_0_0.webp]] client给server发送FIN报文,和一个序列号A server收到后FIN后,把序列号A+1作为报文的序列号,并发送ACK报文告诉client收到了 server发送FIN报文,和一个序列号, client收到FIN后,发送一个SYN报文和服务器序列号+1,告诉服务器收到了。

Read more ⟶