JS ES6 面试题 - 简单题 & 编程题

三、简答题(共2题,每题10分, 20分)

 
1. 阐述Promise解决了什么问题,它如何解决的,async和await又解决了什么问题?
 
Promise使用一种标准的模式来解决异步问题,使得异步处理有章可循。它将一个异步任务分为两个阶段,unsettled和settled,unsettled阶段有权力将异步任务推向settled阶段。同时,它将异步任务划分为3种状态:pending、resolved、rejected,无论是resolved还是rejected,都属于settled阶段,pending一定属于unsettled阶段。状态一定是从pending改变到resolved或rejected中的任意一种,一旦改变,状态不可逆。状态可以附带数据,该数据可以被后续处理所接收。后续处理通过then或catch注册,有两种,分别处理resolved状态或rejected状态。

async和await是ES7的关键字,用于进一步简化Promise的操作,它可以让我们像编写同步代码那样处理Promise

2. 阐述什么是迭代器、可迭代协议、可迭代对象、生成器

迭代器是一个普通的对象,内部提供了next方法,调用后得到一个包含value和done属性的对象,value属性表示这一次迭代得到的数据,done指示是否迭代完成。

可迭代协议是一个规范,如果某个对象拥有知名符号Symbol.iterator,并且该符号是一个迭代器创建函数,则该对象满足可迭代协议

只要满足可迭代协议的对象,称之为可迭代对象

生成器本质上既是一个可迭代对象、又是一个迭代器。它是由生成器函数创建的。生成器函数一定返回一个生成器,它的出现是为了方便迭代器的编写,我们可以通过yield关键字不断的产生迭代结果,并且通过生成器控制迭代过程

四、编程题(共2题,每题10分,20分)

 
1. 有一个字符串数组urls,里面存放了很多的请求地址,现在需要同时向这些地址发送ajax请求,并把每次请求的JSON结果按照响应的先后顺序依次保存到一个新数组results里面,当所有请求完成后,把新数组results输出
 
results数组中每一项的对象格式如下:

{
  requestTime: 日期对象,   //开始请求的时间
  data: 对象,  //服务器响应的结果
  responseTime: 日期对象   //响应的时间
}

答案;

const urls = ["1.json", "2.json"]; //模拟urls数组
const results = []; //用于存放结果
const proms = urls.map(async (url) => {
    const r = {
        requestTime: new Date()
    }
    r.data = await fetch(url).then(resp => resp.json());
    r.responseTime = new Date();
    results.push(r);
})
Promise.all(proms).then(() => {
    console.log(results);
})

 
2. 编写一个函数createDomProxy,该函数返回一个DOM对象的代理,该代理可以将DOM对象以on开头的属性(即事件)变为Promise对象,可以让后续的开发者这样使用这个函数createDomProxy:

async function test() {
    const div = document.getElementById("test"); //得到某个div dom
    const divProxy = createDomProxy(div); //创建它的代理
    while (true) { //使用一个死循环,是为了不断的监听它被点击
        const e = await divProxy.onclick //等待它被点击,e是事件参数
        console.log("div被点击了", e) //被点击后运行的代码
    }
}

test();

答案:

function createDomProxy(dom) {
    return new Proxy(dom, {
        get(target, prop) {
            if (prop.startsWith("on")) {
                return new Promise(resolve => {
                    target.addEventListener(prop.replace("on", ""), e => {
                        resolve(e);
                    }, { once: true })
                })
            }
            return Reflect.get(target, prop);
        }
    })
}