day-067-sixty-seven-20230510-前端开发中的同步异步编程-Promise基础知识深入-ES6小知识-手写Promise源码基础版-简历说明
前端开发中的同步异步编程
前端异步任务
- 宏任务 macrotask
- setTimeout/setInterval
- 事件绑定/队列
- XMLHttpRequest/Fetch
- MessageChannel
- setImmediate「Node」
- node.js中使用。浏览器目前没有。
- 微任务 microtask
- requestAnimationFrame
- 有争议,有人认为是宏任务
- 浏览器页面刷新前调用,这里的代码一旦执行后,浏览器便会开始刷新。适用做动画之类的css效果。
- Promise.then/catch/finally
- 这个是指向他们传递的回调函数是异步的,这些方法本身是同步执行的。
- then()是立即执行的,但是给then传递的onfulfilled/onrejected,他们的执行是异步的。
- 这个是指向他们传递的回调函数是异步的,这些方法本身是同步执行的。
- async/await
- queueMicrotask
- MutationObserver
- IntersectionObserver
- process.nextTick「Node」
- node.js中使用。浏览器目前没有。
- requestAnimationFrame
进程与线程
- 进程和线程
- 一个进程中,包含一到多个线程
- 进程:指的是一个程序(或者是浏览器打开一个页卡,就是开辟一个进程)
- 线程:干活的,一个程序中可能需要同时做多件事情,此时就需要开辟多个线程
- 一个线程同时只能干一件事件
- 一个进程中,包含一到多个线程
- 同步编程
- 只有一个线程,所以同时只能干一件事件,只有当上一件事件处理完毕,下一事件才能处理。
- 线程有运行和空闲两个状态
- 只有一个线程,所以同时只能干一件事件,只有当上一件事件处理完毕,下一事件才能处理。
- 异步编程
- 当前进程(程序)具备多个线程,可以同时处理多件事件,上一件事件即便没有处理完毕,也可以安排一个其它线程去处理,主线程可以继续向下执行!
- 现代浏览器是一个多进程多线程的软件。
- 浏览器是多线程的
- 每一次加载页面,浏览器都会分配很多线程,去同时做一些事件,此时来提高页面的渲染速度。
GUI渲染线程
:渲染和解析HTML与css的,以及最后绘制出相应的页面。- HTML与CSS规范是w3c的。
JS引擎线程
:渲染和解析JavaScript代码的。- JavaScript中ES是ECMA委员会的。
- 这个就是主线程。
定时器监听线程
:监听定时器的。事件监听线程
:监听DOM事件的。HTTP网络请求线程
:发送网络请求,从服务器获取资源的。- …
- 每一次加载页面,浏览器都会分配很多线程,去同时做一些事件,此时来提高页面的渲染速度。
- 浏览器是多线程的
- JavaScript是单线程的:因为浏览器只分配了一个
JS引擎线程
去渲染解析JavaScript代码。- 在JavaScript中大部分代码都是同步代码。
- 例如:循环…
- 但是JavaScript中也有异步代码。
- 通过事件循环EventLoop来做。
- 在JavaScript中大部分代码都是同步代码。
代码执行流程
-
代码执行流程是根据EventLoop事件循环机制来做的。
-
EventLoop事件循环机制涉及概念。
- 主线程:会自上而下执行JavaScript代码。
- 起源于ECStack执行环境栈。
- 一行代码约等于1纳秒,比1毫秒要低个数量级。
- webAPI队列:任务监听队列。
- 目的:监听异步任务是否可以执行。
- 可以被执行的异步任务将会被它送到EventQueue队列中。
- 定时器中设置的等待时间,这个时间是其最快执行的时间。
- 因为到了时间,定时器也不一定能够执行,可能在EventQueue中排队等待着呢!
- 只有主线程下来,它才可能会被安排执行!
- 浏览器会分配定时器监听线程去监听一个异步任务是否可以被执行了。
- 因为到了时间,定时器也不一定能够执行,可能在EventQueue中排队等待着呢!
- 目的:监听异步任务是否可以执行。
- EventQueue队列:事件队列/任务队列
- 目的:所有可执行的异步任务,都会在这个队列中,排队等待执行!
- 浏览器空闲时,每次会来这取一次队列中的异步任务。
- 不确定一次是取一个,还是取当前全部的异步任务。
- 可以做一个执行时间超过10毫秒的微任务,任务中间再插入一个微任务。看是新插入的微任务先执行,还是之前就存在的宏任务先执行。
-
微任务先执行,就是每次取一个异步任务,之后就先执行这一个异步任务。
console.time("异步任务-宏任务1-2"); console.time("同步任务1"); console.time("异步任务-宏任务1-1"); console.time("异步任务-微任务"); console.time("同步任务2"); console.time("同步任务3"); console.time("异步任务-宏任务2-1"); console.time("同步任务4"); console.time("异步任务-宏任务3-1"); console.time("同步任务5"); setTimeout(() => { console.timeEnd("异步任务-宏任务1-2"); // console.log("异步任务-宏任务1-2"); }, 20); console.timeEnd("同步任务1"); // console.log("同步任务1"); setTimeout(() => { console.timeEnd("异步任务-宏任务1-1"); // console.log("异步任务-宏任务1-1"); queueMicrotask(() => { console.timeEnd("异步任务-微任务"); // console.log("异步任务-微任务"); }); }, 10); console.timeEnd("同步任务2"); // console.log("同步任务2"); for (let i = 0; i < 90000000; i++) { // do soming } console.timeEnd("同步任务3"); // console.log("同步任务3"); setTimeout(() => { console.timeEnd("异步任务-宏任务2-1"); // console.log("异步任务-宏任务2-1"); }, 2); console.timeEnd("同步任务4"); // console.log("同步任务4"); setTimeout(() => { console.timeEnd("异步任务-宏任务3-1"); // console.log("异步任务-宏任务3-1"); }, 3); console.timeEnd("同步任务5"); // console.log("同步任务5"); //---------------------------------------- //同步任务1: 0.047119140625 ms //同步任务2: 0.14501953125 ms //同步任务3: 68.099853515625 ms //同步任务4: 68.2099609375 ms //同步任务5: 68.2822265625 ms //返回 undefined -- 这里是最后一行同步代码的返回值。 //异步任务-宏任务1-1: 68.489990234375 ms //异步任务-微任务: 68.5400390625 ms //异步任务-宏任务1-2: 68.593994140625 ms //异步任务-宏任务2-1: 69.541748046875 ms //异步任务-宏任务3-1: 71.5439453125 ms
- 这个结论是对的,微任务先行。也就是说,浏览器主线程空闲后,会到EventQueue队列中取一次,执行一次,之后如果队列还有,就马上再取一次。每次取都是先取微任务的第一个,如果没微任务,就取第一个宏任务。如果宏任务中间插入一个微任务,那就先取微任务。如果队列没有了,那么主线程大概每2ms取一次。
-
宏任务先执行,就是每次取多个异步任务-全部微任务与宏任务,之后按顺序执行完,再去取下一次EventQueue队列中的排队队列。
- 这个是错的,是微任务先执行。
-
- 可以做一个执行时间超过10毫秒的微任务,任务中间再插入一个微任务。看是新插入的微任务先执行,还是之前就存在的宏任务先执行。
- 不确定一次是取一个,还是取当前全部的异步任务。
- 浏览器空闲时,每次会来这取一次队列中的异步任务。
- 主线程空闲后,会每间隔5ms去EventQueue中找一次。
- 或者是每间隔10ms到13ms去EventQueue中找一次。
- 主线程每次找时,只会依次执行一个任务,执行好之后再去执行下一个。
- 目的:所有可执行的异步任务,都会在这个队列中,排队等待执行!
- 主线程:会自上而下执行JavaScript代码。
-
EventLoop事件循环机制
- 当主线程自上而下执行代码的时候,遇到一个异步任务,会立即把其放到WebAPI队列中进行监听。
- 浏览器会分配其它的线程来监听。
- 监听这个异步任务是否可以执行或什么时候能执行。
- 浏览器会分配其它的线程来监听。
- 当异步任务被监测到可以执行了,也不会立即执行,而是挪到EventQueue队列中,排队等待执行。
- 根据任务的类型,分别进入徽任务和宏任务队列中排队。
- 当同步代码执行完毕,或者是主线程空闲下来,会去EventQueue队列中,把排队的异步任务,拿到栈内存中,交给主线程去执行!
- 执行完这个异步任务,主线程又空闲了,再去EventQueue中找其它排队的任务执行!
- EventQueue队列中的任务执行,是有优先级的:
- 异步微任务会优先于异步宏任务执行。
- 换句话讲:只要有可执行的微任务,永远都是先执行微任务,再执行宏任务。
- 异步微任务会优先于异步宏任务执行。
- EventQueue队列中的任务执行,是有优先级的:
- 执行完这个异步任务,主线程又空闲了,再去EventQueue中找其它排队的任务执行!
- 监听异步任务是否可以执行,是webAPI线程来做的,所以基本上把异步任务放到EventQueue队列时的顺序不会有问题。
setTimeout(() => { console.log(1); }, 20); console.log(2); setTimeout(() => { console.log(3); }, 10); console.log(4); console.time("AA"); for (let i = 0; i < 90000000; i++) { // do soming } console.timeEnd("AA"); //=>AA: 79ms 左右 console.log(5); setTimeout(() => { console.log(6); }, 8); console.log(7); setTimeout(() => { console.log(8); }, 15); console.log(9);
- 当主线程自上而下执行代码的时候,遇到一个异步任务,会立即把其放到WebAPI队列中进行监听。
-
备注
-
用JavaScript给定时器设置等待时间,这个等待时间是其最快执行的时间。
- 因为到了时间,定时器也不一定能够执行,可能在EventQueue中排队等待着呢!
- 只有主线程下来,它才可能会被安排执行!
- 因为到了时间,定时器也不一定能够执行,可能在EventQueue中排队等待着呢!
-
给定时器等待时间设置为0,也不是让其立即执行,也需要等待
-
等待流程为:webAPI–>EventQueue
setTimeout(() => { console.log('定时器1') // while (1) { } }, 0) //定时器等待时间设置为0,也不是让其立即执行,也需要等待「WebAPI->EventQueue」
-
-
死循环会让主线程一直被占用着,那么后续所有的事件,包括异步任务的执行都将处理不了了
- 真实项目中千万不要出现死循环的原因就是因为这。
-
没死循环
console.log('start') setTimeout(() => { console.log('定时器1') // while (1) { } }, 0) //定时器等待时间设置为0,也不是让其立即执行,也需要等待「WebAPI->EventQueue」 console.log('handler....') setTimeout(() => { console.log('定时器2') }, 10) // while (1) { } //死循环会让主线程一直被占用着,那么后续所有的事情(包括异步任务的执行都将处理不了了),真实项目中千万不要出现死循环 console.log('end')
-
死循环在主线程-同步代码
console.log('start') setTimeout(() => { console.log('定时器1') // while (1) { } }, 0) //定时器等待时间设置为0,也不是让其立即执行,也需要等待「WebAPI->EventQueue」 console.log('handler....') setTimeout(() => { console.log('定时器2') }, 10) while (1) { } //死循环会让主线程一直被占用着,那么后续所有的事情(包括异步任务的执行都将处理不了了),真实项目中千万不要出现死循环 console.log('end')
- 页面可能都渲染不出来,或者是页面渲染出来后,窗口就直接卡死了。
-
死循环在主线程-异步代码
console.log('start') setTimeout(() => { console.log('定时器1') while (1) { }//死循环会让主线程一直被占用着,那么后续所有的事情(包括异步任务的执行都将处理不了了),真实项目中千万不要出现死循环 }, 0) //定时器等待时间设置为0,也不是让其立即执行,也需要等待「WebAPI->EventQueue」 console.log('handler....') setTimeout(() => { console.log('定时器2') }, 10) console.log('end')
- 内容渲染出来了,但事件一执行,窗口卡死。
-
- 真实项目中千万不要出现死循环的原因就是因为这。
-
-
例子:
console.time("异步任务-宏任务1-2"); console.time("同步任务1"); console.time("异步任务-宏任务1-1"); console.time("异步任务-微任务"); console.time("同步任务2"); console.time("同步任务3"); console.time("异步任务-宏任务2-1"); console.time("同步任务4"); console.time("异步任务-宏任务3-1"); console.time("同步任务5"); setTimeout(() => { console.timeEnd("异步任务-宏任务1-2"); // console.log("异步任务-宏任务1-2"); }, 20); console.timeEnd("同步任务1"); // console.log("同步任务1"); setTimeout(() => { console.timeEnd("异步任务-宏任务1-1"); // console.log("异步任务-宏任务1-1"); queueMicrotask(() => { console.timeEnd("异步任务-微任务"); // console.log("异步任务-微任务"); }); }, 10); console.timeEnd("同步任务2"); // console.log("同步任务2"); for (let i = 0; i < 90000000; i++) { // do soming } console.timeEnd("同步任务3"); // console.log("同步任务3"); setTimeout(() => { console.timeEnd("异步任务-宏任务2-1"); // console.log("异步任务-宏任务2-1"); }, 2); console.timeEnd("同步任务4"); // console.log("同步任务4"); setTimeout(() => { console.timeEnd("异步任务-宏任务3-1"); // console.log("异步任务-宏任务3-1"); }, 3); console.timeEnd("同步任务5"); // console.log("同步任务5"); //---------------------------------------- //同步任务1: 0.047119140625 ms //同步任务2: 0.14501953125 ms //同步任务3: 68.099853515625 ms //同步任务4: 68.2099609375 ms //同步任务5: 68.2822265625 ms //返回 undefined -- 这里是最后一行同步代码的返回值。 //异步任务-宏任务1-1: 68.489990234375 ms //异步任务-微任务: 68.5400390625 ms //异步任务-宏任务1-2: 68.593994140625 ms //异步任务-宏任务2-1: 69.541748046875 ms //异步任务-宏任务3-1: 71.5439453125 ms
Promise基础知识深入
- Promise:ES6新增的API,是一个构造函数,代表的是承诺者设计模式。
-
作为构造函数,只能被new执行,不能作为普通函数执行。
-
因为它可以被认为是基于class创建的类。
- 扩展:
- 基于class创建的类,是不能当做普通函数来执行的。
- Promise就类似于class创建的类。
- 基于class创建的类,是不能当做普通函数来执行的。
Promise() //TypeError: Promise constructor cannot be invoked without 'new' 作为构造函数,只能被NEW执行,不能作为普通函数执行「扩展:基于class创建的类,是不能当做普通函数执行的」
- 扩展:
-
-
不兼容IE,需要导入@bable/polyfill对其进行重写,以此来兼容IE浏览器。
-
基于承诺者设计模式,能够有效地去管理异步编程,避免传统上
基于回调函数的方式管理异步编程
所带来的回调地狱问题。- 这个就是它最初被创立的原因。
- 尤其是其再配合async/await语法糖,可以让异步操作看起来和同步一样,管理起来更方便。
-
异步编程的探索
-
基于回调函数的方式管理异步编程
-
延时函数内部再执行延时函数
-
缺点就是回调地狱。
// 需求:编写一个delay延迟函数,执行delay函数,可以把我们要做的事件延迟一段时间执行。 // 传统方案:基于回调函数的方式,管理异步任务执行期间,要处理的事情 const delay = function delay(interval, callback) { if (typeof interval === "function") { // 其实传递的函数是要给callback的 callback = interval; interval = 1000; } interval = +interval; if (isNaN(interval)) interval = 1000; if (typeof callback !== "function") callback = Function.prototype; let timer = setTimeout(() => { callback(); clearTimeout(timer); }, interval); }; // 回调地狱:回调函数中嵌套回调函数「不方便阅读和开发维护」 delay(1000,() => { console.log("AAA"); delay(1000,() => { console.log("BBB"); delay(1000,() => { console.log("CCC"); }); }); });
-
-
延时函数内部再执行延时函数的并行式处理
- 缺点是得计算出具体延时时间。
- 同时这个计算出来的延时时间,并不能保证一定会是先执行前面的,之后再执行后面的,中间等待的延期时间就是我们所预期的或之后的。
-
比如预期在执行A后1000ms,再那之后经过1000ms再执行B。因为定时器定时的是1000ms,如果同步操作还经过了很长才执行,那么A与B都会进入EventQueue队列中,就会出现A执行结束后,立马就执行B的场景。
const delay = function delay(interval, callback) { if (typeof interval === "function") { // 其实传递的函数是要给callback的 callback = interval; interval = 1000; } interval = +interval; if (isNaN(interval)) interval = 1000; if (typeof callback !== "function") callback = Function.prototype; let timer = setTimeout(() => { callback(); clearTimeout(timer); }, interval); }; // 回调地狱:回调函数中嵌套回调函数「不方便阅读和开发维护」 delay(1000, () => { console.log("AAA"); }); delay(1000 + 1000, () => { console.log("BBB"); }); delay(1000 + 1000 + 1000, () => { console.log("CCC"); });
-
- 同时这个计算出来的延时时间,并不能保证一定会是先执行前面的,之后再执行后面的,中间等待的延期时间就是我们所预期的或之后的。
- 缺点是得计算出具体延时时间。
-
jQuery中提供的$.ajax方法,就是基于传统的回调函数方式,来管理异步的XMLHttpRequest请求
-
-
基于Promise方式的探索:
- 延时函数内部再执行延时函数
- 回调函数式-不return返回一个Promise。
- Promise承诺者模式-执行结束后再返回一个Promise。
- 配合async/await。
- axaj串行
- 延时函数内部再执行延时函数
-
基于async与await的探索:
ajax的串行和并行
- ajax的串行和并行
- 串行:请求之间有依赖,只有等待上一个请求成功,才能发送下一个请求
- 传统的回调函数的解决方式的场景就是回调地狱。
- 并行:多个请求之间没有依赖,可以同时发送多个请求,谁先请求回来,就先处理谁!
- 扩展需求:等待所有请求都结束,统一做点其它操作。
- 串行:请求之间有依赖,只有等待上一个请求成功,才能发送下一个请求
Promise构造函数特点
-
Promise得用new执行。
Promise()//会报错 // Promise() //TypeError: Promise constructor cannot be invoked without 'new' 作为构造函数,只能被NEW执行,不能作为普通函数执行「扩展:基于class创建的类,是不能当做普通函数执行的」
-
new执行Promise时,要求Promise中必须传递一个executor执行函数。
new Promise()//会报错,需要一个函数入参。 // new Promise() //TypeError: Promise resolver undefined is not a function NEW执行的时候,要求Promise中必须传递一个 executor 执行函数
-
返回一个Promise实例
const executor=()=>{}//executor let p1 = new Promise(executor) console.log(p1)
-
Promise实例
- Promise实例
- 私有属性
- [[PromiseState]]:
- [[PromiseResult]]:
- 公有方法
- promiseObject.then()
- then()是立即执行的,但是给then传递的onfulfilled/onrejected,他们的执行是异步的。
- promiseObject.catch()
- promiseObject.finally()
- Symbol(Symbol.toStringTag): “Promise”
- promiseObject.then()
- 私有属性
- 学习Promise的时候,需要:
- 要知道如何创建一个Promise实例
- new Promise()
- Promise的各种静态方法
- async的返回值
- 并且了解如何修改实例的状态和值
- 通过调用函数中的resolve与reject方法
- 最后掌握then/catch/finally等方法执行的契机及操作过程中的一些细节
- 要知道如何创建一个Promise实例
Promise场景
- 第一种:基于new Promise来创建一个promise实例
-
会把传递进来的executor回调函数并
立即执行
。- 这个是同步的过程。
-
而其会给executor函数传递两个实参,用于修改实例的状态。
-
一般会基于resolve/reject两个形参变量来接收传递的实参
- resolve/reject接收的实参值都是函数
- resolve([value]):立即把实例的状态改为fulfilled,实例的值改为[value]
- reject([reason]):立即把实例的状态改为rejected,实例的值改为[reason]
- resolve/reject接收的实参值都是函数
-
实例的状态一旦被从pending改为其它状态值,则后续没有办法再修改此实例的状态和值了。
let p1 = new Promise((resolve, reject) => { resolve(100); reject(0); }); console.log(p1);
-
-
状态改变之后,用then()来接收,根据状态来修改它的东西。
-
ES6小知识
-
Function.prototype的原型是一个空匿名函数()=>{},而不是一个对象
callback=Function.prototype//Function.prototype的原型是一个空匿名函数function(){} // 相当于 //callback=function(){}
-
ES6中有一个属性 new.target:
-
queueMicrotask是ES6的,它是创建一个异步微任务。
-
它内部是一个回调函数,放到队列中就会等待,必定能执行。
console.log(1111); queueMicrotask(()=>{ console.log(2222); }) console.log(3333); //"1111" //"3333" //"2222"
-
手写Promise源码基础版
(function () {
"use strict";
// 为对象设置不可枚举的属性
var define = function define(obj, key, value) {
Object.defineProperty(obj, key, {
writable: true,
configurable: true,
enumerable: false,
value: value,
});
};
// 确保是 Promise 类的实例
var ensureInstance = function ensureInstance(obj) {
if (!(obj instanceof Promise))
throw new TypeError(
"Method Promise.prototype.then called on incompatible receiver " + obj
);
};
// 基于定时器模拟 queueMicrotask 创建异步微任务「我们创建的是异步宏任务」
var queueTask = function queueTask(callback) {
if (typeof queueMicrotask !== "undefined") {
return queueMicrotask(callback);
}
var timer = setTimeout(function () {
callback();
clearTimeout(timer);
}, 0);
};
/* 构造函数 */
var Promise = function Promise(executor) {
var self = this;
if (!(self instanceof Promise))
throw new TypeError(
"Promise constructor cannot be invoked without 'new'"
);
if (typeof executor !== "function")
throw new TypeError("Promise resolver undefined is not a function");
// 为实例设置私有属性:状态和值
define(self, "state", "pending");
define(self, "result", undefined);
define(self, "onfulfilledCallback", []);
define(self, "onrejectedCallback", []);
// 修改实例状态和值
var change = function change(state, result) {
if (self.state !== "pending") return; //状态一但被更改过,则后续不能再更改了
self.state = state;
self.result = result;
// 通知集合中的方法执行「异步微任务」
queueTask(function () {
var callbacks =
self.state === "fulfilled"
? self.onfulfilledCallback
: self.onrejectedCallback;
callbacks.forEach(function (callback) {
callback(self.result);
});
});
};
// 立即执行 executor 函数
try {
executor(
function resolve(value) {
change("fulfilled", value);
},
function reject(reason) {
change("rejected", reason);
}
);
} catch (err) {
// 如果 executor 函数执行报错,也会把实例的状态改为失败,值就是报错原因
change("rejected", err);
}
};
/* 原型对象 */
var proto = Promise.prototype;
define(proto, "then", function then(onfulfilled, onrejected) {
var self = this;
ensureInstance(self);
switch (self.state) {
case "fulfilled":
queueTask(function () {
onfulfilled(self.result);
});
break;
case "rejected":
queueTask(function () {
onrejected(self.result);
});
break;
default:
self.onfulfilledCallback.push(onfulfilled);
self.onrejectedCallback.push(onrejected);
}
});
/* 暴露API「支持各种环境」 */
/* if (typeof window !== 'undefined') window.Promise = Promise
if (typeof module === 'object' && typeof module.exports === 'object') module.exports = Promise */
})();
/*
ES6中有一个属性 new.target :存储被 new 的目标
+ 普通函数执行,存储的值是 undefined
+ 构造函数执行,new.target 就是被 new 的那个构造函数
ES6中新增一个 queueMicrotask 的API,目的:创建一个可执行的异步微任务
queueMicrotask(() => {
...
})
*/
简历说明
- 2023年角色薪酬
- 前端小白 大学科班、了解前端知识、能做demo 实习3-6k
- P4 初级前端 基础知识扎实、可辅助做项目 7-9k 也可能6-8k
- P5 初中级前端 基础扎实、了解部分原理、可独立开发中小型项目 10-14k
- P5+ 中高级前端 基础扎实、掌握核心原理、可独立开发项目、掌握优化和封装技巧 15-20k 也可能13-18k
- 核心原理:vue2及vue3
- 封装axios、vuex、utils工具函数
- 引入第三方框架
- P6 高级或半架构 在之前的基础上,需要具备丰富的项目经验,在工作中处理重难点业务,主要做一些底层架构,知识面要广一点 20-25k
- P7 架构师 慢慢脱离业务层,只做底层架构,具备很强的开发思想和经验。掌握大项项目的架构方案,具备低代码、微前端等项目的构建能力 25k+
- 能力一般上调一级
- 简历写好,先写纸质,挪到平台上
- 模版网上找,找简洁的,尽量不要用平台上的
- 简历就写2页,打死不超过3页
- 3页一般也不看,只看2页
- 可用二维码
- 导到个人网站
- 个人网页也可以放一个电子版简历
- 导到个人网站
- 基本信息
- 姓名
- 性别
- 年龄-到出生年月或多少岁-可多加一两年,说是计划生育
- 户籍-到市
- 工作年限-具备到多少年,向上取
- 邮箱-163邮箱,手机要有邮箱应用
- 电话-24小时开机
- 学历-本科及以上再加
- 政治面貌-非党员不要写,共青团员不要写,群众也是
- 头像问题
- 二维码
- 电子版简历
- 花哨、技术含量、用css的
- 博客的二维码
- 项目地址
- 个人网站
- 放个人项目
- 电子简历
- 项目地址
- 电子版简历
- 二维码
- 求职信息
- 职位:前端开发,尽量别只写一个品类
- web、app、h5、小程序
- 期望薪资:面议或者是一个范围
- 个人应该至少13k
- 建议列一个最低薪资,往上提1k,让面试官杀价
- 何时到岗
- 随时到岗或已离职
- 职位:前端开发,尽量别只写一个品类
- 自我介绍、专业技能、个人优势
- 用简短的语言,罗列出所会的技术
- 说广度,如react开发、vue2、vue3、小程序、ts
- 突出项目实战,或者封装、优化、源码能力
- 出深度
- 自己多总结招聘需求,根据需求去编写
- 如果写的文字多,将重点词汇加粗
- 爱好
- AI绘画、AI唱歌
- 用简短的语言,罗列出所会的技术
- 参考能力方案
- html5及css3及响应式布局方案,可100%还原设计稿
- 掌握less与scss等预编译语言,熟练掌握flex与grid等布局技巧
- 掌握JavaScript及ES6规范
- 掌握Promise、async与await、generator、iterator、proxy、reflect、fetch等应用
- 掌握面对对象编程思想
- 框架–重点
- 其它:个人博客、个人网站
- 工作经历
- 那年到那年(至今) 公司名字 职务-前端开发
- 描述:公司是干什么的,在什么部门,主要负责什么,做了那些东西,可以加用了那些技术,公司有多少人1000左右
- 工作经历:
- 4年两家,这个个人真实,一份至少两年。
- 最后一份至少两年,不可写太多。
- 大厂一般会背调,中厂也可能是。
- 一般至少要3年,这个个人符合。
- 4年两家,这个个人真实,一份至少两年。
- 常见问题
- 学信网是否可查
- 个人本科,没必要写假。假的民办本科听说在淘宝上有。
- 别搞假的,可能犯法。
- 个人身份证也可能是,听说有些人连身份证都是假的。
- 技术人员分配
- 前端多少,后端多少
- 薪资
- 薪人薪事–一个网站
- 离职证明
- 真实或淘宝或自己P,个人有真实的,没必要
- 这个一般别人是查不了真的
- 收入证明
- 真实或淘宝或自己P,个人有真实的,没必要
- 这个一般别人是查不了真的
- 个人本科,没必要写假。假的民办本科听说在淘宝上有。
- 学信网是否可查
- 项目经历
- 至少4个,至多6个
- 项目版块
- 自己的项目的主要负责人,负责了70%的开发
- 要用数字
- 业绩
- 面向c端
- 技术
- 秋c
- 封装
- 提取业务组件
- UI组件的二次封装
- utils公共方法封装
- axios与fetch的封装
- 代理的设置
- vuex的封装,分模块
- 插件的封装
- 常用插件
- pdf打印、预览
- 富文本编辑器
- 大文件上传
- Excel表格的上传和下载及打印,及预览
- 鉴权
- 语言切换
- 下拉刷新
- 弹幕
- …
- 封装
- 秋c
- 招聘平台:
- BOSS直聘
- 主要的
- 一般一天200个
- 智联网
- 不要期待,也尽量海投
- 一天500多个
- 51job-前程无忧
- 尽量别试,公司不太好
- 拉钩网
- 尽量别试,公司不太好
- 猎聘网
- 公司比较大
- 得好好准备,面试题较难0
- …
- 和前端相关,就批量海投
- 投递简历的时间
- 周一-周六 早上09:30开始 下午14:00开始
- 不要睡懒觉
- 周一-周六 早上09:30开始 下午14:00开始
- BOSS直聘
- 面试中一些叮嘱
- 大胆出去面试,以面养面
- 忘的速度要快于学的速度,所以尽快面试
- 面试的时候,可以自己刷一些常见的面试题
- 做好面试总结:记得录音
- 大胆出去面试,以面养面