ロックインする時間
Javascriptの非同期関数は、真に並列ではありません。 ES2017以降、Javascriptは同時関数呼び出しをサポートしています。違いは、次のステートメントでMadhavan Nagarajanによって非常にうまく要約されています(リンクは補遺にあります)。
並行性とは、一度に多くのことを処理することです。並列処理とは、一度に多くのことを実行することです。
Javascriptの同時実行性の実装は、その機能が削減され、シンプルで非常に堅牢なAPIを使用できるようになります。異なる非同期呼び出しによる同じ変数へのアクセスを処理する場合、非同期関数は中断できず、揮発性プロパティの概念もありません。 ES2017の非同期関数の詳細な実装はこの記事の範囲外ですが、私が伝えたい主なポイントは、これまで、並列処理はJavascriptとWebに組み込まれていなかったため、同じエンティティ。しかし、「Web Locks API」の導入により、状況は変わりました。
すべてに1つ、すべてに1つ
プログレッシブウェブアプリがWebWorkersとServiceWorkerの導入により、真のマルチスレッドアーキテクチャを提供するようになったため、状況は変化しました。 Webアプリでは真の並列処理が可能であるため、並列コードを処理するためのより高度なツールが必要になります。
ロックは、リソースへのアクセスを要求するメカニズムであり、任意の時点で1つのプロセスのみが実際にアクセスできることを保証します。この方法でリソースをロックすると、他の方法で発生する可能性のある多数の競合領域を回避できます。
リソースは、文字列で識別される単なる名前空間です。また、「Web Lock API」を実装するために必要なのは、IDと関数コールバック(ほとんどの場合非同期)だけであるため、リソースへのアクセス要求も同様に単純です。 1つの非同期機能が終了すると、ロックが解除され、他のリクエストが再びアクセスできるようになります。
/*
* A simple demonstration of the Web Lock API.
* Note that this example has been taken from
* MDN's awesome documentation, linked in the
* addendum.
*/
async function foo(){
// A common async function that you already know.
const data = await getData();
// Request the lock.
// Note that we can simply await the locked call!
await navigator.locks.request('lock_resource_id', async lock => {
// The lock has been acquired.
// At this point, this call has exlusive access
// to the resource 'lock_resource_id'.
await updateDb(data);
// Now the lock will be released.
});
// The lock has been released.
// Continuse with plain async calls.
await updateUi();
}
この新しいAPIは実験的な状態であるため、有効なフォールバックを使用して、コード内のオプション機能として扱う必要があります。
/**
* Due to the usage of web locks in core parts
* of your app, actually using the API this way
* might introduce more problems then it could solve.
*
* Therefore a thorough specification in your app
* has to be implementation before using this feature.
*/
async function update(){
if(navigator?.locks){
// Run logic with lock.
} else {
// Use fallback.
}
}
この新しいAPIをわかりやすく説明するために、簡単な例を見てみましょう。メインプロセスと2つのWebWorkerを備えたマルチスレッドPWAがあるとします。また、アプリはIndexDBを使用し、データベースとの間で変更をクラウドと同期するカスタムコードを使用します。このシナリオで「WebLockAPI」を使用すると、すべてのプロセスが、データベースへの変更を同期するために定義されたロックへのアクセスを要求でき、この呼び出し中に他のミューテーションが実行されないようにします。
「WebLockAPI」は、Webアプリで副作用なしに単一の変数を変更することではなく(明らかにユースケースになる可能性があります)、並列アーキテクチャで関数呼び出しを処理することを目的としていることに注意してください。負の副作用。
学ぶべきこと
この記事では、現在実験段階にあり、主にChromiumベースのブラウザでサポートされている新しい「WebLocksAPI」についてのみ紹介しました。 APIは、ここで説明するより多くのオプションを提供し、一見の価値があります。