序文
数日前、私はほとんどの友人が知っているこの問題の議論は、私はこれは非常に興味深いです感じたので、記録として、この記事を書きます
スカウトの友人から派生品のアイデアやプロジェクトのコードsimon3000 @は、私はより理解のニーズを満たすように変更する必要があります。
ここでは、コードが許可された当事者に使用されるように、以下を参照してください。
非常に多くの彼の理解と励ましをいただき、ありがとうございます
最初のコードのアドレスに
(元のバージョンのディレクトリは、元のコードの作成者であるその下プロジェクトにページ)
問題を作成Webworker JSファイルとパスによってもたらさ
次のように、実行するための追加のJSファイルを作成する必要がありそうなのでWebworkerは、実際には、私はいつも、比較的堅いの使用と感じています
VaRの労働者= 新しいワーカー( 'work.js')
これは、追加のjsファイルを作成する必要があることを意味します。このように、それは私が少し感じさせる「昔ながらの。」貧しいファイルのJSを操作する能力ので、あなたがファイルを作成したい場合は、当然のことながら、方法がある、参照:https://github.com/eligrey/FileSaver.js/
あなたは、ファイル、JSファイルの作成、多くの場合、不可分のダウンロードを作成したい場合はしかし、問題は、あります!私は、ファイルを作成することを「静かに」しようとしていたが、それが作成されたときに結果JSが突然ダウンロードボックスをポップアップ、それは耐え難いことができます。ああ、不快。(ここでは表現パッケージ[私のために難しい]でなければなりません)。
つまり、この時間webWorkerが「静的」で、ある余分な-JSファイルは、制約されています。
4回の変換は、WebWorkerを課し通常の関数、となります
しかしsimon3000 @勧告私は輝いてみましょう!彼は、と言ってくれましたwebworkerローダー(WebPACKのテクノロジ・スタック)を使用して、自分の経験に基づいて、通常の関数WebWorkerになるための直接的な方法の連続変換があります
これは非常にエキサイティングな情報です。
ただ、彼の行動を見て:
// 文件名为main.js function work () { onmessage = ({data: {message}}) => { console.log ('i am worker, receive:' + message); postMessage ({result: 'message from worker'}); }; } const runWorker = f => { const worker = new Worker ( URL.createObjectURL (new Blob ([`(${f.toString ()})()`])) ); worker.onmessage = ({data: {result}}) => { console.log ('i am main thread, receive:' + result); }; worker.postMessage ({message: 'message from main thread'}); }; const testWorker = runWorker (work);
这段代码是我在他的代码基础上简化的
输出结果:
用Promise和闭包的方式去改造
我们再让它更通用一些,用Promise和闭包的方式去改造它,把runworker函数改造成一个makeworker函数
// 文件名为index.js function work () { onmessage = ({data: {jobId, message}}) => { console.log ('i am worker, receive:-----' + message); postMessage ({jobId, result: 'message from worker'}); }; } const makeWorker = f => { let pendingJobs = {}; const worker = new Worker ( URL.createObjectURL (new Blob ([`(${f.toString ()})()`])) ); worker.onmessage = ({data: {result, jobId}}) => { // 调用resolve,改变Promise状态 pendingJobs[jobId] (result); // 删掉,防止key冲突 delete pendingJobs[jobId]; }; return (...message) => new Promise (resolve => { const jobId = String (Math.random ()); pendingJobs[jobId] = resolve; worker.postMessage ({jobId, message}); }); }; const testWorker = makeWorker (work); testWorker ('message from main thread').then (message => { console.log ('i am main thread, i receive:-----' + message); });
输出结果
总结
这次探讨告诉我们什么道理呢?
-
第一,function.toString得到的并不是一个没有意义的字符串,它是完全可以被用来运行的
-
第二,通过这种方式,webworker不需要借助额外的JS文件了,webworker完全动态化和自由化,你可以在主线程中创建任意个webworker!
-
第三,我通过这次的交谈了解到一个道理,编程除了考量逻辑思维,信息差也是考量的一大因素。我之前也想过用webworker做这些事情,可是我不知道能用这样的四重转换呀!我也不知道function.toString得到的字符串居然是有作用的。信息差,也是会造成差距的。所以工程上也经验和前瞻也同样重要。
其他参考资料
-
worker-loader源码: https://github.com/webpack-contrib/worker-loader