Почему canvas.toBlob и canvas.toDataURL имеют разные типы возврата - PullRequest
1 голос
/ 09 марта 2019

canvas.toBlob () требует функцию обратного вызова, но canvas.toDataURL () возвращает результат синхронно. Почему разница? Это не проблема, но мне очень любопытно, и я не могу найти объяснения, почему это так.

1 Ответ

1 голос
/ 12 марта 2019

Потому что toDataURL была ранняя ошибка ...

На момент его реализации (Safari IIRC) FileAPI еще только обсуждался, и экспорт результата canvas был уже необходим. Таким образом, они создали этот метод, который возвращает данные в удобном URL-адресе данных, который можно использовать непосредственно как src нескольких элементов в документе. В настоящее время синхронное возвращение звучит как хорошая идея, все в Canvas API было синхронным.

Но несколько лет спустя, со все большим количеством реализаций, все большим количеством применений и новыми API, стало очевидно, что toDataURL не была хорошей идеей. Точно так же, как синхронный XHR, если вы достаточно взрослый, чтобы помнить.
Несмотря на то, что вы можете иметь URL-адрес данных синхронно, его отображение в любом случае будет асинхронным.

Чтобы создать файл изображения из холста, это медленная операция, вам необходимо экспортировать все данные пикселей, разумножить их, а затем вызвать алгоритмы сжатия.

Кроме того, URL-адрес данных должен храниться в виде строки в кодировке base64, на 34% превышающей двоичные данные, которые он представляет, и копироваться в память каждый раз, когда вы назначаете его где-то в DOM ...

FileAPI представил способы хранения двоичных данных в памяти, чтобы иметь возможность отображать их, манипулировать ими или отправлять на сервер как есть. Все это подразумевает минимальные затраты памяти => URL-адреса данных устарели (в большинстве случаев).

Поэтому было решено добавить новый метод, который бы использовал эти новые API и который возвращал бы Blob вместо URL-адреса данных. В общей борьбе с операциями блокировки пользовательского интерфейса было решено, что этот метод будет асинхронным (но, к сожалению, это было до прихода Promise ...) . Теперь все, что нужно делать синхронно, это захватывать данные пикселей, как это делает getImageData. Остальные операции можно выполнять параллельно.

...