女娲大战虫族,背后到底有多少故事?

勾勾的前端世界

共 3934字,需浏览 8分钟

 ·

2020-12-14 19:46

嗨,我是你稳定更新、持续输出的勾勾。



相传远古时代,天塌地陷,世界陷入巨大灾难。女娲不忍生灵受灾,于是炼五色石补好天空,折神鳖之足撑四极,平洪水杀猛兽,通阴阳除逆气,万灵始得以安居。


女娲补天,不仅仅是个神话故事。


女娲补天,事实上补的是虫洞。


神话是上一个纪元的历史,而虫洞的对面是地球的敌人。


所以要补上虫洞,阻断对面虫族的进攻通道。


当科技发展到一定程度,人类会探索到连接不同时空的隧道。


人类通过虫洞可以去到异度空间,而异度空间的朋友也可以来到我们的世界。


当世界与世界,空间与空间之间的道路被打通。


战争一触即发!


双方开战,世界再次陷入混战。


在这个时候,女娲后人血脉觉醒,决定承担起拯救苍生的重任。


这个时候,难题来了。


题目是这样写的:


在 urls 数组中存放了 10 个接口地址。同时还定义了一个 loadDate 函数,这个函数接受一个 url 参数,返回一个 Promise 对象,该 Promise 在接口调用成功时返回 resolve,失败时返回 reject。


要求:任意时刻,同时下载的链接数量不可以超过 3 个。试写出一段代码实现这个需求,要求尽可能快速地将所有接口中的数据得到。


var urls = [  'http://jsonplaceholder.typicode.com/posts/1',  'http://jsonplaceholder.typicode.com/posts/2'  'http://jsonplaceholder.typicode.com/posts/3'  'http://jsonplaceholder.typicode.com/posts/4',  'http://jsonplaceholder.typicode.com/posts/5'  'http://jsonplaceholder.typicode.com/posts/6'  'http://jsonplaceholder.typicode.com/posts/7'  'http://jsonplaceholder.typicode.com/posts/8',  'http://jsonplaceholder.typicode.com/posts/9'  'http://jsonplaceholder.typicode.com/posts/10']function loadDate (url{  return new Promise((resolve, reject) => {    const xhr = new XMLHttpRequest()    xhr.onload = function ({      resolve(xhr.responseText)    }    xhr.open('GET', url)    xhr.send()  })}


这道题目,对很多人真的很难。


但是,难不倒会炼五色石的女娲后人!


因为,他是学前端的!

因为,他是伟大的切图仔!


他缓缓道来:“按照题意,可以这样做。”


首先并发请求 3 个 url 中的数据,当其中一条 url 请求得到数据后,再继续发起对一条 url 上数据的请求。


要始终让并发数保持在 3 个,直到所有需要加载数据的 url 全部都完成请求并得到了数据。


用 Promise 实现的思路是,首先并发请求3个  url ,得到的 3 个 Promise ,然后组成一个叫  promises 的数组。


再不断地调用 Promise.race 来返回最快改变状态的 Promise ,然后从数组 promises 中删掉这个 Promise 对象,再加入一个新的 Promise,直到所有的 url 被取完,最后再使用 Promise.all 来处理一遍数组(promises)中没有改变状态的 Promise。


最终输出如下:

var urls = [  'http://jsonplaceholder.typicode.com/posts/1',  'http://jsonplaceholder.typicode.com/posts/2'  'http://jsonplaceholder.typicode.com/posts/3'  'http://jsonplaceholder.typicode.com/posts/4',  'http://jsonplaceholder.typicode.com/posts/5'  'http://jsonplaceholder.typicode.com/posts/6'  'http://jsonplaceholder.typicode.com/posts/7'  'http://jsonplaceholder.typicode.com/posts/8',  'http://jsonplaceholder.typicode.com/posts/9'  'http://jsonplaceholder.typicode.com/posts/10']
function loadDate (url{  return new Promise((resolve, reject) => {    const xhr = new XMLHttpRequest()    xhr.onload = function ({      resolve(xhr.responseText)    }    xhr.open('GET', url)    xhr.send()  })}
function limitLoad(urls, handler, limit{    // 对数组做一个拷贝    const sequence = [].concat(urls)let promises = [];        //并发请求到最大数    promises = sequence.splice(0, limit).map((url, index) => {        // 这里返回的 index 是任务在 promises 的脚标,用于在 Promise.race 之后找到完成的任务脚标        return handler(url).then(() => {            return index        });  });
    // 利用数组的 reduce 方法来以队列的形式执行    return sequence.reduce((last, url, currentIndex) => {        return last.then(() => {            // 返回最快改变状态的 Promise            return Promise.race(promises)        }).catch(err => {            // 这里的 catch 不仅用来捕获 前面 then 方法抛出的错误            // 更重要的是防止中断整个链式调用            console.error(err)        }).then((res) => {            // 用新的 Promise 替换掉最快改变状态的 Promise            promises[res] = handler(sequence[currentIndex]).then(() => { return res });        })    }, Promise.resolve()).then(() => {        return Promise.all(promises) })
}limitLoad(urls, loadDate, 3)
/*因为 loadDate 函数也返回一个 Promise,所以当 所有图片加载完成后,可以继续链式调用
limitLoad(urls, loadDate, 3).then(() => {    console.log('所有url数据请求成功');}).catch(err => {    console.error(err);})*/


答案出来了,虫洞也终于补上了!


而全世界人类因为受到异族的荼毒,得上了重病。


为了医治全人类,科学家研发出了疫苗,需要女娲后人动用古老的力量传播给所有人。


女娲后人用最普遍存在的介质,也就是泥土做为媒介,承载着疫苗,飞天泼洒。


于是有了女娲补天、女娲造人的历史记载。


在数万年人们的口口相传中,女娲逐渐被神化。


历史便成了传说。


悟空,你悟了吗?


推荐阅读:

三篇短文让你学会 NextJS(三)

三篇短文让你学会 NextJS(二)

三篇短文让你学会 NextJS(一)

手动实现一个自己的 React 服务端渲染

不会真的有人不知道 API 如何设计吧。

别再复制粘贴了!高效工作神器—— plop

API 终结者 —— 杀手 Reflect

前端人因为 Vue3 的 Ref-sugar 提案打起来了!

CRA 为什么要做成“黑盒”


点点“”和“在看”,保护头发,减少bug。

浏览 42
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报