JS 面试总结 理论篇

JS为什么是单线程?

由于浏览器可以渲染DOM,JS也可以修改DOM结构,未避免冲突,JS执行的时候,浏览器DOM渲染会停止。
两段JS不能同时执行。

虽然 HTML5 中新引入的webworker支持多线程,但是不能访问DOM

浏览器允许的并发资源数限制,如何突破?

不同浏览器的并发请求数目限制不同

image.png

因为浏览器的并发请求数目限制是针对同一域名的。

  • 所以可以多设置子个域名来突破限制,比如简书的图片子域名upload-images.jianshu.io
  • 把资源文件放到CDN上,如https://cdn2.jianshu.io/assets/web-f5f4ced5c8b8a95fc8b4.js

单线程的解决方案,异步

和PHP不一样,写的代码顺序和执行的顺序是不一致的,PHP是同步。

console.log(100)
// 等其他JS代码执行完才开始执行
setTimeout(()=> {
 console.log(200)
}, 10000)

console.log(300)

类似的ajax也是

console.log(100)
// 等其他JS代码执行完才开始执行
$.ajax({
   url: 'xxx',
   success: res => {
      console.log(res)
   }
})
console.log(300)

这样有个弊端,可读性差

event loop 事件轮询

  • 同步代码,直接执行
  • 异步函数先放到异步队列中,待同步函数执行完毕,轮询执行异步队列的函数
  • 触发异步函数有 setTimeout,setImmediate,setInterval

实例1

setTimeout(() => console.log(1), 100)
setTimeout(() => console.log(2))
console.log(3)

显示顺序是: 3 2 1

image.png

实例2

image.png

显示顺序: d c a b 或 d c a b
这是由于ajax的success回调函数被放入异步队列的时间是不确定的,当然如果是本地测试,有可能的顺序是 d a...

image.png

关于$ajax的底层

jquery的 $ajax 实际上是对 XMLHttpRequest 对象的封装

xmlhttp.open( "GET", "some/ur/1", true );
xmlhttp.onreadystatechange = function( data ) {
    if ( xmlhttp.readyState === 4 ) {
        console.log( data );
    }
};
xmlhttp.send( null );

底层的XmlHttpRequest对象发起请求,设置回调函数用来处理XHR的readystatechnage事件。
然后执行XHR的send方法。在XHR运行中,当其属性readyState改变时readystatechange事件就会被触发,
只有在XHR从远端服务器接收响应结束时回调函数才会触发执行

jQuery的$ajax的async 参数设置同步或异步的本质是?

关于$ajax 中的 async 参数
async默认的设置值为true,这种情况为异步方式,就是说当ajax发送请求后,在等待server端返回的这个过程中,前台会继续 执行ajax块后面的脚本,直到server端返回正确的结果才会去执行success。
其本质是 xhrReq.open(method, url, async)

JS 异常有做上报处理吗?是什么实现的

  • 捕获异常的方法通过使用 try...catch
try {
    var a = 1;
    var b = a + c;
} catch (e) {
    // 捕获处理
    console.log(e); // ReferenceError: c is not defined
}

缺点:增加代码量和维护性,不适用于整个项目的异常捕获。

  • window.onerror
    相比try catch来说window.onerror提供了全局监听异常的功能:
window.onerror = function(errorMessage, scriptURI, lineNo, columnNo, error) {
    console.log('errorMessage: ' + errorMessage); // 异常信息
    console.log('scriptURI: ' + scriptURI); // 异常文件路径
    console.log('lineNo: ' + lineNo); // 异常行号
    console.log('columnNo: ' + columnNo); // 异常列号
    console.log('error: ' + error); // 异常堆栈信息
};

console.log(a);
image.png

提交异常

window.onerror = function(errorMessage, scriptURI, lineNo, columnNo, error) {
    // 构建错误对象
    var errorObj = {
        errorMessage: errorMessage || null,
        scriptURI: scriptURI || null,
        lineNo: lineNo || null,
        columnNo: columnNo || null,
        stack: error && error.stack ? error.stack : null
    };

    if (XMLHttpRequest) {
        var xhr = new XMLHttpRequest();
        xhr.open('post', '/middleware/errorMsg', true); // 上报给node中间层处理
        xhr.setRequestHeader('Content-Type', 'application/json'); // 设置请求头
        xhr.send(JSON.stringify(errorObj)); // 发送参数
    }
}
  • Vue 的捕获异常
    在MVVM框架中如果你一如既往的想使用window.onerror来捕获异常,那么很可能会竹篮打水一场空,或许根本捕获不到,因为你的异常信息被框架自身的异常机制捕获了。使用Vue.config.errorHandler这样的Vue全局配置,可以在Vue指定组件的渲染和观察期间未捕获错误的处理函数。这个处理函数被调用时,可获取错误信息和Vue 实例。
Vue.config.errorHandler = function (err, vm, info) {
  // handle error
  // `info` 是 Vue 特定的错误信息,比如错误所在的生命周期钩子
  // 只在 2.2.0+ 可用
}
  • React 的 异常处理 -- Error Boundary
    同样的在react也提供了异常处理的方式,在 React 16.x 版本中引入了 Error Boundary
class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false };
    }

    componentDidCatch(error, info) {
        this.setState({ hasError: true });

        // 将异常信息上报给服务器
        logErrorToMyService(error, info); 
    }

    render() {
        if (this.state.hasError) {
            return '出错了';
        }

        return this.props.children;
    }
}

使用

<ErrorBoundary>
    <MyWidget />
</ErrorBoundary>

参考:https://www.cnblogs.com/luozhihao/p/8635507.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,198评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,334评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,643评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,495评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,502评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,156评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,743评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,659评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,200评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,282评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,424评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,107评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,789评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,264评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,798评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,435评论 2 359

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,512评论 1 45
  • $HTML, HTTP,web综合问题 1、前端需要注意哪些SEO 3、HTTP的几种请求方法用途 4、从浏览器地...
    peng凯阅读 773评论 0 1
  • 前端开发面试题 面试题目: 根据你的等级和职位的变化,入门级到专家级,广度和深度都会有所增加。 题目类型: 理论知...
    怡宝丶阅读 2,588评论 0 7
  • PNG 有PNG8和truecolor PNG PNG8类似GIF颜色上限为256,文件小,支持alpha透明度,...
    hudaren阅读 1,536评论 0 0
  • Ajax和XMLHttpRequest 我们通常将Ajax等同于XMLHttpRequest,但细究起来它们两个是...
    changxiaonan阅读 2,240评论 0 2