一些场景题

63 阅读4分钟

1.避免回调地狱:

(1)使用promise链式调用;
(2)使用async/Await;
(3)使用promise.all并行处理任务,promise.race竟态处理任务;

开发中遇到的内存泄露问题

1.addeventlistener未清除;
可以在componentWillUnmount时期清除,或者useEffect这个hook的return中清除
2.滥用闭包;
3.定时器没有清除
4.DOM引用未释放
const elements = {
  button: document.getElementById('myButton'),
};
// 即使从DOM移除button,JS引用仍阻止GC回收
document.body.removeChild(elements.button); 
一些没什么用的全局变量
// 使用严格模式
"use strict"; 

function foo() {
  bar = "value"; // 严格模式下报错
}
5.Nodejs的特定的泄露:未关闭的数据库连接,未关闭文件流;
// 数据库连接
db.connect();
db.close(); // 显式关闭

监测:

浏览器环境(Chrome DevTools)

Performance 监控

-   录制操作过程,观察JS Heap内存曲线是否持续上升

Memory 快照

-   拍摄堆快照(Heap Snapshot),对比操作前后的对象保留树

Allocation instrumentation

-   跟踪内存分配时间线,定位泄露对象

浏览器有哪些兼容问题

系统级解决方案

工程化工具

-   使用PostCSS自动添加CSS前缀(如Autoprefixer)。
-   用Babel转译ES6+代码兼容旧浏览器。
-   引入Polyfill库(如`core-js`)补充缺失API。

测试与调试

-   浏览器测试工具:BrowserStack、Sauce Labs。
-   开发者工具:Chrome DevTools的兼容性检查、Firefox响应式设计模式。

渐进增强策略
优先保证基础功能在所有浏览器可用,再为现代浏览器添加高级特性(如CSS动画)。 核心原则

  • 优先使用标准语法(如Flex布局替代float)9。
  • 避免Hack:少用_*等CSS Hack,改用特性检测(Modernizr)。
  • 及时更新:关注浏览器支持终止公告(如[Chrome淘汰Android 7.1]1)。

A页面打开定时器,在B页面怎么关闭;什么样的情况下两个页面能处理到这个定时器;

页面需要处于同一浏览器上下文(同源)单页面应用; A打开B的方式是window.open()

1.localStorage.setItem('timerStatus', 'running');
let timer = setInterval(() => { /* 定时器执行的代码 */ }, 1000);
-A 页面添加 storage 事件监听器,用于接收关闭定时器的信号:

    -   `window.addEventListener('storage', (e) => { if (e.key === 'timerStatus' && e.newValue === 'stop') { clearInterval(timer); } });`
    -B 页面,当需要关闭定时器时,修改 localStoragesessionStorage 中的标识符:

    -   `localStorage.setItem('timerStatus', 'stop');`

还有一个使用服务端的方法,调用服务端关闭;

postmessage方法
-A 页面设置定时器:

    -   `let timer = setInterval(() => { console.log('定时器执行'); }, 1000);`
-A 页面添加消息监听:

    -   `window.addEventListener('message', (event) => { if (event.data === 'stopTimer') { clearInterval(timer); } });`
-B 页面,使用 `window.opener.postMessage()` 方法向 A 页面发送消息。`window.opener` 是 B 页面的一个属性,它指向打开 B 页面的 A 页面的窗口对象:

    -   `window.opener.postMessage('stopTimer', 'A页面的源');`

token失效怎么处理

后端会验证token是否失效,一般约定401失效,然后用户跳到登陆页面;

防止前端重复请求

1.防抖节流; 2.禁用按钮直到结果返回或者超时;

不同域共享cookie

同一主域下的不同子域名之间共享 Cookie

在设置 Cookie 时,通过指定 Domain 属性为主域名,可以让不同子域名共享该 Cookie。例如,对于 www.example.comsub.example.com,可以设置 Domain=example.com,这样两个子域名都能访问该 Cookie。

使用cors: 前端

// 使用fetch API
fetch('https://api.other-domain.com/data', {
  method: 'GET',
  credentials: 'include' // 关键设置:携带Cookie
});

// 使用axios
axios.get('https://api.other-domain.com/data', {
  withCredentials: true // 关键设置:携带Cookie
});

// 使用XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.other-domain.com/data', true);
xhr.withCredentials = true; // 关键设置:携带Cookie
xhr.send();

后端

const express = require('express');
const app = express();

// CORS中间件
app.use((req, res, next) => {
  // 必须指定具体域名(不能使用通配符*)
  res.setHeader('Access-Control-Allow-Origin', 'https://your-client-domain.com');
  
  // 必须设置为true
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  
  // 允许的请求方法
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
  
  // 允许的请求头
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  
  // 处理预检请求
  if (req.method === 'OPTIONS') {
    return res.sendStatus(200);
  }
  
  next();
});

// 设置Cookie
app.get('/set-cookie', (req, res) => {
  res.cookie('sessionId', '12345abcde', {
    httpOnly: true,
    secure: true, // 必须使用HTTPS
    sameSite: 'None', // 跨域必需
    maxAge: 24 * 60 * 60 * 1000 // 有效期1天
  });
  res.json({ message: 'Cookie已设置' });
});

前端必须设置

-   `credentials: 'include'` (fetch)
-   `withCredentials: true` (axios/XHR)

后端必须设置

-   `Access-Control-Allow-Origin`: 具体域名(非通配符*)
-   `Access-Control-Allow-Credentials: true`
-   Cookie属性:`Secure` + `SameSite=None`

如何把px转换为rem

核心组件:postcss-pxtorem

  • rootValue (基准值): 1rem对应的px值(通常设置为设计稿宽度/10)
  • unitPrecision: 转换后保留的小数位数
  • propList: 需要转换的属性列表(* 表示所有属性)
  • selectorBlackList: 不需要转换的选择器
  • minPixelValue: 最小转换值(小于这个值不转换)
  • mediaQuery: 是否在媒体查询中转换px 要写一个postcss.config.js文件
  1. 开发阶段:开发者使用px单位编写CSS样式
  2. 构建阶段:PostCSS处理CSS文件,将所有px单位转换为rem
  3. 运行时:JavaScript根据屏幕宽度动态设置根字体大小
  4. 渲染时:所有rem单位基于根字体大小进行渲染 构
建流程中,CSS文件需要通过loader进行处理,而PostCSS作为CSS处理器,需要在CSS加载过程中介入。2. 在Webpack等构建工具中,loader用于对模块的源代码进行转换。PostCSS通过postcss-loader集成到Webpack的loader链中。
// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /.css$/,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [
                  require('postcss-pxtorem')({
                    rootValue: 16,
                    propList: ['*']
                  })
                ]
              }
            }
          }
        ]
      }
    ]
  }
}