Web worker
作用:
为javascript创造多线程环境(允许主线程创造worker线程,将一些任务分配给后者运行),这样的好处是,一些计算密集型或高延迟的任务,被worker线程负担了,主流程就会很流畅,不会被阻塞或延慢。
使用限制:
1、同源限制:分配给worker线程运行的脚本文件,必须与主线程的脚本文件同源。
2、文件限制:worker线程无法读取本地文件(file://),会拒绝使用file协议创建worker实例,它所加载的脚本必须来自网络。
3、DOM操作限制:worker线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的DOM对象,无法使用document,window,parent这些对象
4、通信限制:worder线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过信息完成。交互的方法分别是postMessage和onmessage,并且在数据传递的时候,worker是使用拷贝的方式。
5、脚本限制:worker线程不能执行alert()和confirm(),但可以使用ajax请求,setTimeout和setInterval等API。
例:
Const worker=new Worker(URL, options)
Worker.postMessage:向worker的内部作用域发送一个消息,消息由任何javascript对象组成。
Worker.terminate:立即终止worker,该方法并不会等待worker去完成它剩余的操作,将会立即停止。
Worker.onmessage:当worker的父级接受到来自worker的消息时,会在worker对象上触发message事件
Worker.onerror:当worker出现运行错误时,它的onerror事件处理函数会被调用,它会收到以扩展了errorEvent接口的名为error的事件
Web worker的执行上下文名称时 self | this,无法调用主线程的window对象的。
worker线程内部要加载其他脚本,可以使用importScripts()
URL对象,创建内嵌的worker。
<script id="worker" type="javascript/worker">
this.addEventListener('message', (e) => {
console.log('wokerEvent', self, e);
postMessage(`Blob worker线程接收到的消息:::${e.data}`)
})
</script>
<script>
const blobWorkerScript = document.querySelector('#worker').textContent
const blob = new Blob([blobWorkerScript], { type: 'text/javascript' })
const worker = new Worker(window.URL.createObjectURL(blob))
</script>
promise
class MyPromise {
constructor(executor) {
this.initValue()
this.initBind()
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e)
}
}
initBind() {
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
}
initValue() {
this.promiseResult = null;
this.promiseState = 'pending';
}
resolve(value) {
if (this.promiseState !== 'pending') return;
this.promiseState = 'fulfilled';
this.promiseResult = value;
}
reject(value) {
if (this.promiseState !== 'pending') return;
this.promiseState = 'rejected';
this.promiseResult = value;
}
}
const p1 = new MyPromise((resolve, reject) => {
resolve('success');
reject('fail');
})
class MyPromise {
constructor(executor) {
this.initValue()
this.initBind()
try {
executor(this.resolve, this.reject);
} catch (e) {
this.reject(e)
}
}
initBind() {
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
}
initValue() {
this.promiseResult = null;
this.promiseState = 'pending';
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
}
resolve(value) {
if (this.promiseState !== 'pending') return;
this.promiseState = 'fulfilled';
this.promiseResult = value;
while (this.onFulfilledCallbacks.length) {
this.onFulfilledCallbacks.shift()(this.promiseResult)
}
}
reject(value) {
if (this.promiseState !== 'pending') return;
this.promiseState = 'rejected';
this.promiseResult = value;
while (this.onRejectedCallbacks.length) {
this.onRejectedCallbacks.shift(this.promiseResult);
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
var thenPromise = new MyPromise((resolve, reject) => {
const resolvePromise = cb => {
try {
var x = cb(this.promiseResult);
if (x === thenPromise && x) {
throw new Error('不能返回自身')
}
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
resolve(x)
}
} catch (err) {
reject(err)
throw new Error(err)
}
}
if (this.promiseState === 'fulfilled') {
resolvePromise(onFulfilled)
} else if (this.promiseState === 'rejected') {
resolvePromise(onRejected)
} else if (this.promiseState === 'pending') {
this.onFulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled));
this.onRejectedCallbacks.push(resolvePromise.bind(this, onRejected));
}
})
return thenPromise
}
}
const p3_1 = new MyPromise((resolve, reject) => {
resolve(10)
}).then(res => {
return new MyPromise((resolve, reject) => {
resolve(res * 10)
})
}).then(res => {
console.log('last==', res)
})
const p3_2 = new MyPromise((resolve, reject) => {
resolve(10)
}).then(res => {
return res * 2
}).then(res => {
console.log('last222==', res)
})
const p3_3 = new MyPromise((resolve, reject) => {
resolve(10)
}).then(res => {
return p3_3
}).then(res => {
console.log('last222==', res)
}, e => console.log('error', e))
promise方法
/**
* ? all
* 1. 接收一个Promise数组, 数组中如有非Promise项, 则此项当做成功
* 2. 如果所有Promise都成功, 则返回成功结果数组
* 3. 如果有一个Promise失败, 则返回这个失败结果
*/
// Promise.all([p1, p3]).then((res) => {
// console.log('res==', res)
// }).catch(e => console.log(e))
/**
* ? race
* 1. 接收一个Promise数组, 数组中如有非Promise项, 则此项当做成功;
* 2. 哪个Promise最快得到结果, 就返回哪个结果, 无论成功失败
*/
// Promise.race([p1, p2, p3]).then((res) => console.log(res)).catch(e => console.log(e))
/**
* ? allSettled
* 1. 接收一个Promise数组, 数组中如有非Promise项, 则此项当做成功
* 2. 把每一个Promise的结果, 集合成数组后返回
*/
// Promise.allSettled([p1, p2, p3]).then((res) => console.log(res)).catch(e => console.log(e))
/**
* ? any 与all相反
* 1. 接收一个Promise数组, 数组中如有非Promise项, 则此项当做成功
* 2. 如果有一个Promise成功, 则返回这个成功结果
* 3. 如果所有Promise都失败, 则报错
*/
Promise.any([p1, p2, p3]).then((res) => console.log('any', res)).catch(e => console.log(e))