Problem
BarcodeDetector.detect() returns a Promise<DetectedBarcode[]> that resolves only after the entire image has been analyzed.
For large images (for example, scanned A4 documents containing dozens of QR codes), this means applications cannot process any detected barcodes until detection has completely finished.
This introduces unnecessary latency for use cases where consumers could start processing results immediately as they are found.
Proposal
Introduce an asynchronous iterator-based API that yields detected barcodes progressively.
For example:
for await (const barcode of barcodeDetector.detec(image)) {
console.log(barcode.rawValue);
}
or
const stream = barcodeDetector.detectStream(image);
for await (const barcode of stream) {
// Process each barcode immediately
}
Benefits
- Lower perceived latency.
- Applications can start processing or displaying results immediately.
- Better support for large images containing many barcodes.
- Makes cancellation more practical by allowing consumers to stop iteration once sufficient results have been found.
- Fits naturally with modern JavaScript async iteration patterns.
Use case
Consider an A4 document containing 100 QR codes.
With the current API:
- Analyze the entire image.
- Detect all 100 codes.
- Resolve the promise.
- Begin processing.
With an async iterator:
- Begin analyzing the image.
- Yield the first detected QR code.
- Continue scanning while the application processes earlier results.
- Continue until scanning completes or the consumer cancels iteration.
Notes
This proposal would be an addition rather than a replacement for detect(). The existing API would remain appropriate for cases where all results are needed at once, while an async iterator would better support streaming and low-latency workflows.
One possible API shape could be:
interface BarcodeDetector {
detect(source: ImageBitmapSource): Promise<DetectedBarcode[]>;
detectStream(
source: ImageBitmapSource,
options?: DetectOptions
): AsyncIterable<DetectedBarcode>;
}
This would align with the growing use of AsyncIterable in the web platform for APIs capable of producing results incrementally.
A AbortSignal would be benefitial here as well... barcodeDetector.detectStream(image, { signal: AbortSignal.timeout(1000) })
Also many usecases involve scanning a live video feed continuously (#99, #108) until we say that we are done.
It would be helpful if this also connected well together with the async-iterator-helpers
So it would be sweet if detectStream could continuously parse a hole video instead of a single video frame.
(some form of memory cache would be needed so that same barcode isn't yield:ed multiple times)
Problem
BarcodeDetector.detect()returns aPromise<DetectedBarcode[]>that resolves only after the entire image has been analyzed.For large images (for example, scanned A4 documents containing dozens of QR codes), this means applications cannot process any detected barcodes until detection has completely finished.
This introduces unnecessary latency for use cases where consumers could start processing results immediately as they are found.
Proposal
Introduce an asynchronous iterator-based API that yields detected barcodes progressively.
For example:
or
Benefits
Use case
Consider an A4 document containing 100 QR codes.
With the current API:
With an async iterator:
Notes
This proposal would be an addition rather than a replacement for
detect(). The existing API would remain appropriate for cases where all results are needed at once, while an async iterator would better support streaming and low-latency workflows.One possible API shape could be:
This would align with the growing use of
AsyncIterablein the web platform for APIs capable of producing results incrementally.A AbortSignal would be benefitial here as well...
barcodeDetector.detectStream(image, { signal: AbortSignal.timeout(1000) })Also many usecases involve scanning a live video feed continuously (#99, #108) until we say that we are done.
It would be helpful if this also connected well together with the async-iterator-helpers
So it would be sweet if detectStream could continuously parse a hole video instead of a single video frame.
(some form of memory cache would be needed so that same barcode isn't yield:ed multiple times)