Web Worker 的一些简单使用
Web Workers 用于执行一些耗时的任务,比如数据处理、图像处理、音频处理等,而不会阻塞主线程。今天我们来了解一些 Web Worker 的常用场景。
在 Worker 线程中创建和使用 DOM 对象
在 Worker 线程中,我们无法直接访问主线程中的 DOM 对象,但是我们可以通过 postMessage() 方法将一些 JavaScript 对象或数组发送给主线程,然后在主线程将这些数据加载到 DOM 对象中。例如:
// 主线程
const message = {
name: '编程三昧',
age: 30
};
worker.postMessage(message);
// Worker 线程
const message = await new Promise((resolve, reject) => {
const blob = new Blob([JSON.stringify(message)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => {
resolve(xhr.response);
};
xhr.onerror = () => {
reject(new Error('Failed to fetch data'));
};
xhr.send();
});
console.log(message);
worker.postMessage(message);
在 Worker 线程中进行数据处理
在 Worker 线程中,我们可以使用 Math 对象、Date 对象、JSON 对象等 JavaScript 内置对象来进行数据处理,然后使用 postMessage() 方法将处理后的数据发送回主线程。例如:
// Worker 线程
const message = {
name: '编程三昧',
age: 30
};
const age = Math.floor(message.age / 10);
const name = message.name.split('').reverse().join('');
console.log(`Name: ${name}`);
console.log(`Age: ${age}`);
worker.postMessage({name, age});
// 主线程
const message = {
name: '编程三昧',
age: 30
};
const age = Math.floor(message.age / 10);
const name = message.name.split('').reverse().join('');
worker.postMessage({name, age});
// Worker 线程
const data = await new Promise((resolve, reject) => {
const blob = new Blob([JSON.stringify(data)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => {
resolve(xhr.response);
};
xhr.onerror = () => {
reject(new Error('Failed to fetch data'));
};
xhr.send();
});
worker.postMessage(data);
在这段代码中,我们在 Worker 线程中对传递过来的数据进行了简单的处理,并将处理后的结果发送回主线程。在主线程中,我们使用 postMessage() 方法将原始数据和处理后的结果分别发送回 Worker 线程。
在 Worker 线程中使用 Promise
在 Worker 线程中,我们可以使用 Promise 对象来进行异步操作,比如读取文件、连接数据库、发送网络请求等。在 Worker 线程中,我们需要使用 Promise.all() 方法来等待多个 Promise 对象的执行结果。例如:
// Worker 线程
const files = [
'file1.txt',
'file2.txt',
'file3.txt'
];
const promises = files.map(file => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsText(file);
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = () => {
reject(new Error(`Failed to read file: ${file}`));
};
});
});
Promise.all(promises)
.then(files => {
console.log(files);
worker.postMessage(files);
})
.catch(error => {
console.error(error);
});
// 主线程
const files = [
'file1.txt',
'file2.txt',
'file3.txt'
];
const promises = files.map(file => {
return fetch(`/api/read-file?file=${file}`).then(response => response.text());
});
Promise.all(promises)
.then(data => {
console.log(data);
worker.postMessage(data);
})
.catch(error => {
console.error(error);
});
在这段代码中,我们在 Worker 线程中定义了一个读取文件的 Promise 对象,并将其传递给了 Promise.all() 方法。在主线程中,我们使用 fetch() 方法发送了一个网络请求,并将请求结果传递给了 Promise.all() 方法。在 Worker 线程中,我们等待了所有文件的读取结果,并将其发送回主线程。
转载自:https://juejin.cn/post/7269682017499283471