複数のバーコードのスキャン (従来)
単一スキャンセッションで複数のバーコードをスキャンするには、resumeCapture()
を使用して連続スキャンサイクルを作成します。これは、ユーザが [キャンセル] ボタンをクリックするまでバーコードをスキャンします。
場合によっては、スキャンの間にユーザ操作をせずに、多数のバーコードを連続してスキャンする必要があります。たとえば、在庫の棚をスキャンする場合、1 品目ずつスキャンを終了したり、すべての品目で [スキャン] ボタンをクリックしたりするのは避けたいでしょう。このような場合には、[スキャン] を 1 回クリックするだけで、すべての品目が終わるまで繰り返しバーコードがスキャンされるようにする方が賢明です。このような連続スキャンサイクルの実装は、1 つの品目のスキャンとは若干異なります。
-
通常どおり、
beginCapture()
を使用してスキャンセッションを開始します。 -
Promise が解決されたら、通常どおりスキャンされたバーコードを
then()
ブロックで処理します。Processing the barcode can’t change the user interface, or require interacting with the user. That needs to wait until after the scanning cycle completes.
-
then()
ブロックの最後で、新しい連続スキャン関数をコールします。この関数はresumeCapture()
を使用して現在のスキャンセッションを継続します。 -
finally()
ブロック内ではなく、catch()
ブロックの最後でendCapture()
をコールします。 -
ユーザが [キャンセル] をクリックしてスキャンセッションを終了すると、
BarcodeScanner
はcode
プロパティ値がuserDismissedScanner
のBarcodeScannerError
オブジェクトを返します。catch()
ブロックでキャンセルと実際のエラーを処理します。
単一スキャンと連続スキャンの基本的なスキャンライフサイクルは似ていますが、この 2 つには比較する価値があるほどの明らかな違いがあります。
注意すべき大きな相違点は次の 2 つです。
- 連続スキャンの
then()
ブロックには、新しい関数continueScanning()
へのコールがあります。**「スキャンセッションの継続」**セクションを参照してください。 endCapture()
へのコールは、単一スキャンの場合はfinally()
ブロックで行われますが、連続スキャンの場合はcatch()
エラー処理ブロックで行われます。**「継続スキャンの捕捉の終了」**セクションを参照してください。
上記のコード比較では、スキャンセッションを継続する手法は、continueScanning()
へのコールという新しい行の後ろに隠されていました。次に、その関数の例を示します。
このコードには見覚えがあるはずです。連続スキャンで説明した前述の beginCapture()
の例とほぼ同じです。違いは 1 つだけで、continueScanning()
では、Promise チェーンを作成するために sessionScanner.resumeCapture()
をコールしますが、前述の例では sessionScanner.beginCapture()
をコールしたという点です。当たり前のことかもしれませんが、beginCapture()
をコールするのはスキャンサイクルの開始時に一度だけです。
コードの違いは少ないですが、実行フローの違いはかなりあります。スキャンサイクルは、beginCapture()
で作成された Promise チェーンで開始され、これは 1 回だけ実行されます。その最初の Promise は、次の 2 つの方法のいずれかで解決されます。
- スキャンが成功すると、バーコードの結果が処理され、スキャンサイクルの制御のフローが
continueScanning()
に渡されます。 - ユーザが [キャンセル] をクリックした場合、またはエラーが発生した場合、Promise チェーンは
catch()
エラー処理ブロックで終了します。詳細は、**「継続スキャンの捕捉の終了」**セクションを参照してください。
continueScanning()
の Promise チェーンは、これらと同じ 2 つの方法で終了しますが、重要な違いが 1 つあります。コードは同じですが、スキャンが成功した後、それ自体をコールしてスキャンサイクルを続行し、再帰的なループを作成します。このループは、ユーザが [キャンセル] をクリックするか、エラーが発生するまでスキャンサイクルを継続します。
申し訳ありません。再帰的という単語で怖がらせるつもりはありませんでした。はい、continueScanning()
はそれ自体をコールすることで終了し、再帰関数となります。ただし、この再帰は非常にシンプルな単なるループであり、一種のイベントループです。このループは、user-clicked-Cancel イベント (catch()
ブロック内) が発生するまで scan-something イベント (then()
ブロック内) を処理して、終了します。若干時間がかかるかもしれませんが、理解できるでしょう。
ここでの全体的なパターンは次のようになります。
beginCapture()
を使用してスキャンサイクルを開始します。beginCapture()
からの Promise 解決チェーンは、独自の関数であるcontinueScanning()
へのコールで終了します。continueScanning()
はresumeCapture()
をコールして既存のスキャンサイクルを続行します。ただし、それ以外はサイクルを開始したbeginCapture()
と同じです。continueScanning()
の Promise 解決チェーンは、continueScanning()
へのコールで終了し、スキャンサイクルループを作成します。- ユーザが [キャンセル] をクリックし、
BarcodeScanner
がBarcodeScannerError
で Promise を拒否して、エラー処理のcatch()
ブロックでendCapture()
をコールすると、ループは終了します。
beginCapture()
と resumeCapture()
の Promise チェーン間では残念ながらコード重複が発生しますが、これは避けられません。スキャンしたバーコードの処理などの処理コードを、両方のチェーンからコールできる関数にできるだけ移動させます。ここでの例では、processScannedBarcode()
は、両方の Promise チェーンが成功したスキャンを処理するために使用する関数です。関数の実装を含む完全なサンプルについては、「BarcodeScanner の例 — 連続スキャン (従来)」を参照してください。
連続スキャンセッションでは、ユーザは品目がなくなるまで繰り返し品目をスキャンします。ユーザは [キャンセル] ボタンをクリックして、セッションを終了します。コードでは、BarcodeScanner
は Promise を拒否し、ユーザがスキャンをキャンセルしたことを示す BarcodeScannerError
を返すことでキャンセルを処理します。ユーザによる [キャンセル] のクリックと実際のエラーを区別する方法については、「BarcodeScanner の例 — 連続スキャン (従来)」を参照してください。
重要なのは、[キャンセル] ボタンをクリックすることが連続スキャンセッションを終了する唯一の方法だということです。これは、単一スキャンセッションがスキャンの成功または [キャンセル] ボタンのいずれかで終了するのとは対照的な点です。
連続スキャンは常に [キャンセル] ボタンで終了するため、その結果 BarcodeScannerError
が返され、エラー処理の catch()
ブロックで endCapture()
をコールすることができます。
ただし、単一スキャンは BarcodeScannerError
で終わらない可能性があるため、catch()
ブロックが実行されないことがあります。そのため、単一スキャンでは、endCapture()
を finally()
ブロックに配置して、成功しても失敗しても常にコールされるようにしています。