es6常用功能与异步详解(JS高级面试题)
callback hell方法的使用
可读性不友好
function loadImg(src,callback,fail){
var img = document.createElement('img');
img.onload = function(){
callback(img);
}
img.onerror = function(){
fail();
}
img.src = src;
}
var src = "https://www.baidu.com/img/baidu_jgylogo3.gif";
loadImg(src,function(img){
console.log('img width',img.width)
},function(){
console.log('faild')
})
用promise 去改造
用多个.then去分批处理
function loadImg(src){
return new Promise(function(resolve,reject){
var img = document.createElement('img');
img.onload = function(){
resolve(img);
}
img.onerror = function(){
reject();
}
img.src = src;
})
}
var src="https://www.baidu.com/img/baidu_jgylogo3.gif";
var result = loadImg(src);
result.then(function(img){
console.log('img width',img.width)
},function(){
console.log('faild')
})
result.then(function(img){
console.log('img height',img.height)
})
问题解答:
- new promise实例,而且要传入return
- new promise时要传入函数,函数有resolve reject函数
- 成功时执行resolve()失败时执行reject()
- .then监听结果
ES6常用功能
- let 定义变量,可以重新赋值
- const 定义常量,不可以重新赋值
- 多行字符串/模板变量
- 解构赋值(详情见es6)
- 块级作用域(很大的改动)
- 函数默认参数
- 箭头函数
块级作用域
<!-- 在js里面 -->
var obj = {a:100,b:200}
for (var key in obj) {
console.log(key,'for in')
}
console.log(key) // 100,200
<!-- 在es6 -->
var obj = {a:100,b:200}
for (let key in obj) {
console.log(key,'for in')
}
console.log(key); // undefine
箭头函数改变this指向的问题
<!-- 用箭头函数,指向本身函数对象 -->
function fn(){
console.log('real',this); // {a:100}
var arr = [1,2,3];
arr.map(item=>{
console.log(this); // {a:100}
})
}
fn.call({a:100}); // call是强制让fn函数对象指向{a:100}
<!-- 不用箭头函数,this指向window -->
function fn(){
console.log('real',this); // {a:100}
var arr = [1,2,3];
arr.map(function(item){
console.log(this); // window;
})
}
fn.call({a:100});
原型
描述一下zepto是如何使用原型
描述一下jquery如何使用原型
再结合自己的项目经验,说一个自己开发的列子
$p.css('color','red'); // css是原型方法
$p.html(); // html是原型方法
原型如何体现他的扩展性
异步
问题:
一. 什么是单线程,和异步有什么关系
- 单线程只有一个线程,同一时间只能做一件事情
var i,sum = 0;
for(i=0;i<100000;i++){
sum+=i;
}
console.log(sum);
<!-- alert不处理,js执行和dom渲染暂时卡顿 -->
console.log(1);
alert('hello');
console.log(2);
用单线程的原因-避免DOM渲染的冲突
A. 浏览器需要渲染DOMB. js可以修改DOM结构
C. JS执行的时候,浏览器DOM渲染会暂停
D. 两段JS也不能同时执行(都修改DOM就冲突了)
E. webworder支持多线程,但是不能访问DOM
单线程的解决单线程方案-异步
console.log(100)
setTimeout(function(){
console.log(200);
},1000)
console.log(300);
console.log(400);
// 100
// 300
// 400
// 200 一秒后执行
console.log(100)
$.ajax({
url:'XXXX',
success:function(res){
console.log(res) // 最后执行
}
});
console.log(300)
cobsole.log(400)
异步的问题:
问题一:没有按照书写的方式执行,可读性差
问题二:callback中不容易模块化(setTimeout和ajax里面的函数)
二. 什么是event-loop 异步的解决方案。
- 事件轮询,js实现异步的具体解决方案
- 同步代码,直接执行
- 异步函数先放在异步队列中;有setTimeout等待时间过后,才放入异步队列中。ajax执行完毕过后放入异步队列
- 待同步函数执行完毕,轮询执行异步队列的函数
回答点:
- 什么是异步队列,何时被放入异步队列
- 轮询的过程。
三. 是否用过jquery的deferred
问题解答:
1. 可以拿jquery1.5 对ajax的改变举例
2. 说明如何简单的封装、使用deferred,说出它的好处
3. 说明promise和deferred的区别
jQuery1.5的变化——1.5之前
var ajax = $.ajax({
url:'./data.json',
success:function(){
console.log('success 1');
console.log('success 2');
console.log('success 3');
},
error:function(){
console.log('error');
}
})
jQuery1.5的变化——1.5之后
这样写的好处:
- 这样对修改封闭,对扩展开放,
- 增加一个函数,不用再修改原来的函数
- 多人开发,一人维护一个函数。
- 测试也只测试新的函数。
- 对代码管理和维护有好处的
// 每一个方法都会执行
var ajax = $.ajax('data.json');
ajax.done(function(){
console.log('success 1');
}).fail(function(){
console.log('fail 1');
}).done(function(){
console.log('success 2');
}).fail(function(){
console.log('fail 2');
}).done(function(){
console.log('success 3');
}).fail(function(){
console.log('fail 3');
})
<!-- 与promise很相近了 -->
var ajax = $.ajax('data.json')
ajax.then(function(){
console.log('success 1');
},function(){
console.log('error 1');
}).then(function(){
console.log('success 2');
},function(){
console.log('error 2');
})
- 无法改变js异步和单线程的本质
- 只能从写法上杜绝callback这种形式
- 它是一种语法糖形式,但是解耦了代码
- 很好的体现:开放封闭原则
- 减少了回归测试的成本。多人开发方便。
使用jquery deferred举例:
var wait = function(){
var task = function(){
console.log('执行完成');
}
setTimeout(task,20000)
}
wait();
function waitHandle(){
// 定义
var dtd = $.Deferred();
var wait = function(dtd){
var task = function(){
console.log('执行完毕');
// 成功
dtd.resolve()
// 失败
// dtd.reject()
}
setTimeout(task,2000);
// wait返回
return dtd;
}
// 最终返回
return wait(dtd);
}
var w = waitHandle();
w.then(function(){
console.log('ok 1');
},function(){
console.log('err 1');
})
w.then(function(){
console.log('ok 2');
},function(){
console.log('err 2');
})
w.then(function(){
console.log('ok 3');
},function(){
console.log('err 3');
})
w.reject(); // 不会报错
// 开放封闭原则!!!
总结:
dtd的API可分成两类,用意不同
第一类:dtd.reolve dtd.reject 主动触发
第二类:dtd.then dtd.done dtd.fail 被动监听
初步引入promise概念,是 jquery deferred 引入过来的
promise和jquery deferred的区别:
promise对象只能被动监听,不能主动修改,所以在w.reject()会报错。
function waitHandle(){
// 定义
var dtd = $.Deferred();
var wait = function(dtd){
var task = function(){
console.log('执行完毕');
// 成功
dtd.resolve()
// 失败
// dtd.reject()
}
setTimeout(task,2000);
// wait返回
return dtd.promise(); // 这里返回的是promise对象
}
// 最终返回
return wait(dtd);
}
var w = waitHandle();
$.when(w).then(function(){
console.log('ok 1');
},function(){
console.log('err 1');
}).then(function(){
console.log('ok 2');
},function(){
console.log('err 2');
})
w.reject(); // 这里就会直接报错。
四. promise的基本使用和原理
基本语法回顾
1. 异常捕获
function loadImg(src){
return new Promise(resolve,reject){
var img = document.createElement('img');
img.onload = function(){
resolve(img);
}
img.onerror = function(){
reject('图片加载失败');
}
img.src= src;
}
}
var src="https://wwww.img.address";
var result = loadimg(src);
// 规定:then只接受一个成功的参数,最后统一用catch来捕获错误
result.then(function(img){
console.log(1,img.width);
return img;
}).then(function(img){
console.log(2,img.width);
}).catch(function(ex){
// 统一捕获异常,也会捕获到reject方法
console.log(ex);
})
2. 多个串联
// 场景:希望加载完第一个,再加载第二个
var src1 = 'img.address';
var result1 = loadImg(src1);
var src2 = 'img.address';
var result2 = loadImg(src2);
result1.then(function(img1){
console.log('加载第一章图片',img1.width);
return result2 // 重要!!!
}).then(function(img2){
console.log('加载第二章图片',img2.width);
}).catch(function(ex){
console.log(ex);
})
3. promise.all和promise.race
// Promise.all接收一个promise对象的数组
// 待全部完成之后,统一执行success
Promise.all([result1,result2]).then(datas=>{
// 接收到的datas是一个数组,依次包含了多个promise返回的内容
console.log(datas[0]);
console.log(datas[1]);
})
// Promise.race 接收一个包含多个promise对象的数组
// 只要有一个完成,就执行success
Promise.race([result1,result2]).then(data=>{
// data 是最先执行完成的 promise对象的返回值
console.log(datas);
})
4. promise标准
关于“标准”的闲谈,标准很重要
任何技术推广使用都需要一套标准来支撑
如 html js css http等,无规则不成方圆
任何不符合标准的东西,终将会被用户抛弃
状态变化
三种状态:pending fulfilled rejected
初始状态pending
pending 变成fulfilled,或者pending变为rejected
状态不可逆
then
promise 实例必须实现then这个方法
then()必须可以接收两个函数作参数
then()返回的必须是一个promise实例
问题解答总结:
1. 基本语法复习
2. 如何异常捕获(error和reject都要考虑)
3. 多个串联-链式执行的好处
4. promise.all和promise.race
5. promise标准-状态变化,then函数
五. 介绍一下 async/await
是es7体验中的。
then只是将callback拆分了
async/await是最直接的同步写法
const load = async function(){
const result1 = await loadImg(src1);
console.log(result1);
const result2 = await loadImg(src1);
console.log(result2);
}
load()
语法(和promise的区别和联系)
1. 使用await,函数必须用async标识
2. await 后面跟的是一个promise实例
使用了promise,并没有和promise冲突
完全是同步的写法,再也没有回调函数
但是:改变不了JS单线程、异步的本质
3. 需要安装babel-polyfill并,引入
六. 总结当前js异步解决方案
1. jQuery Deferred
2. Promise
3. async/await
4. generator(并不是解决异步的,原理比较复杂,忽略)
es6常用功能与异步详解(JS高级面试题)的更多相关文章
- Python OS模块常用功能 中文图文详解
一.Python OS模块介绍 OS模块简单的来说它是一个Python的系统编程的操作模块,可以处理文件和目录这些我们日常手动需要做的操作. 可以查看OS模块的帮助文档: >>> i ...
- 触碰jQuery:AJAX异步详解
触碰jQuery:AJAX异步详解 传送门:异步编程系列目录…… 示例源码:触碰jQuery:AJAX异步详解.rar AJAX 全称 Asynchronous JavaScript and XML( ...
- jQuery调用AJAX异步详解[转]
AJAX 全称 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML).它并非一种新的技术,而是以下几种原有技术的结合体. 1) 使用CSS和X ...
- 触碰jQuery:AJAX异步详解(转)
AJAX 全称 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML).它并非一种新的技术,而是以下几种原有技术的结合体. 1) 使用CSS和X ...
- 详解js变量、作用域及内存
详解js变量.作用域及内存 来源:伯乐在线 作者:trigkit4 原文出处: trigkit4 基本类型值有:undefined,NUll,Boolean,Number和Strin ...
- [转]javascript console 函数详解 js开发调试的利器
javascript console 函数详解 js开发调试的利器 分步阅读 Console 是用于显示 JS和 DOM 对象信息的单独窗口.并且向 JS 中注入1个 console 对象,使用该 ...
- VC++常用数据类型及其操作详解
原文地址:http://blog.csdn.net/ithomer/article/details/5019367 VC++常用数据类型及其操作详解 一.VC常用数据类型列表 二.常用数据类型转化 2 ...
- javascript常用经典算法实例详解
javascript常用经典算法实例详解 这篇文章主要介绍了javascript常用算法,结合实例形式较为详细的分析总结了JavaScript中常见的各种排序算法以及堆.栈.链表等数据结构的相关实现与 ...
- Delphi Format函数功能及用法详解
DELPHI中Format函数功能及用法详解 DELPHI中Format函数功能及用法详解function Format(const Format: string; const Args: array ...
随机推荐
- idea+maven+springmvc
黑了Java这么多年, 今天为Java写一篇文章吧. 这篇文章主要是想帮助那些刚接触到Java, 同时想从事Java WEB GUI开发的人. 对我而言, 我很早就有想尝试用Java写WEB的想法, ...
- 在performancepoint里面建立数据源的时候,总是发生以下的报警
就是我在performancepoint里面建立数据源的时候,总是发生以下的报警. 在管理中心主页的“应用程序管理”部分,单击“管理服务应用程序”,然后单击“PerformancePoint Se ...
- Smart Pointer Guidelines
For Developers > Smart Pointer Guidelines What are smart pointers? Smart pointers are a specif ...
- node.js状态码
100——客户必须继续发出请求101——客户要求服务器根据请求转换HTTP协议版本200——交易成功201——提示知道新文件的URL202——接受和处理.但处理未完成203——返回信息不确定或不完整2 ...
- CentOS7的聚合链路
1.环境介绍 [root@rhcc ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) ENERAL.DEVICE: en ...
- 关于vs2012/2013的C编译器生成的exe的向后兼容xp的问题
问题一:编译出来的exe在xp上面运行提示"不是有效的win32应用程序" 在vs2012/2013版本里面,其自带的c编译器cl.exe,若直接使用cl a.c编译,那么生成出来 ...
- mysql 5.7 双主+主从配置
mysql5.7安装及赋权 wget http://repo.mysql.com/mysql57-community-release-el7-8.noarch.rpm rpm -ivh mysql57 ...
- SpringBoot @PathVariable 和 @requestParam区别
1.若获取的入参的 参数 是下面这种形式 就使用 @requestParam 去获取 参数‘1’ /user?id=1 // url:xxx/user?id=1 @RequestMapping(&qu ...
- P2186 小Z的栈函数
P2186 小Z的栈函数 题目描述 小Z最近发现了一个神奇的机器,这个机器的所有操作都是通过维护一个栈来完成的,它支持如下11个操作: NUM X:栈顶放入X. POP:抛弃栈顶元素. INV:将栈顶 ...
- Cocos2d-x学习笔记(20)(TestCpp源代码分析-4)
本章主要介绍testResource.h与tests.h,当中tests.h主要是存放全部用到的头文件.与菜单相相应的宏定义以及菜单数组,testResource.h主要用是资源文件定义. //tes ...