「这是我参与11月更文挑战的第8天,活动详情查看:2021最后一次更文挑战」
最近不禁要感叹 web 发展太快,随着 web 需求不断增长,而且要求越来越高,这是很多浏览器跟不上 js 的脚步了。所以少不了 polyfill 来填坑。
通过 TransformStream() 构造函数可以创建了一个 TransformStream 对象,代表一对 Stream 分别是一个可写端的 WritableStream ,一个可读端为ReadableStream 。
TransformStream 不仅仅简单用作流,实际上可以将其看做一个先进先出的队列。例如,如果有一个事件处理程序,想确保在你处理下一个事件之前,其前一个事件需要处理完成了,只要这些事件输送到一个 TransformStream 中。
但是现在浏览器对 TransformStream 这个 API 支持还不均衡,例如现在firefox 就不支持这个 API。
<script src="/streams-polyfill.js"></script>
<script>
const ts = new TransformStream(/*...*/)
</script>
之前我们都会这样做也就是在执行代码前,放上一个 polyfill.js 这样在执行const ts = new TransformStream(/*...*/)确保这个对象已经存在。
这样做显然问题,因为许多浏览器原生就支持这个 API,这样做,即使代码运行在支持该 API 的浏览器,也无法使用到原生 TransformStream,因为 polyfill 提供对象会作为全局下,所以我们需要选择性加载 polyfill.js
看下面的就是一个有条件导入,这里没有采用静态脚本方式导入
streams-polyfill.js 而是采用的是动态导入import
<script>
(async function(){
if(!('TransformStream' in self)){
await import('/streams-polyfill.js');
}
})()
</script>
这里首先判断是否存在 TransformStream API 如果不存在,我们希望引用streams-polyfill.js并且希望将其挂载到全局,其实我们更希望返回一个对象,然后将该对象挂载到全局上工作交给调用者来做。
<script>
(async function(){
if(!('TransformStream' in self)){
await import('/streams-module.js');
}
const ts = new TransformStream(/*...*/)//undefined
})()
</script>
import {TransformStream} = import('/streams-module.js')
self.TransformStream = TransformStream
这样静态地将streams-module.js 导入解决问题,不过同时也带来了之前问题,就是我们希望是有选择地加载,下面方案才是一个正确的解决方案。
let TransformStreamPromise = Promise.resolve()
.then(()=> {
if('transformStream' in self){
return TransformStream;
}
const {TransformStream} = await import('/stream-module.js');
return TransformStream;
})
(async function(){
const tst = new (await TransformStreamPromise(/**/))
})();
这里采用 Promise 的 resolve 然后,如果 TransformStream 存在就直接将其返回,如果不存则引入后在返回。 在发送端是一个 Promise 对象,直接调用其 resolve 方法返回对象,或者去异步加载该模块,这是一个异步的,在接收端,因为是异步操作,所以可以等待资源准备好了再去调用。