Я опытный программист и недавно вернулся к своей старой страсти и изо всех сил стараюсь вписаться в этот объектно-ориентированный, управляемый событиями яркий новый мир, и хотя я вижу преимущества непоследовательного поведения Javascript, есть время, когда это действительно мешает простоте и возможности повторного использования.
Простой пример, над которым я работал, - это сделать фотографию (мобильный телефон, запрограммированный на javascript, HTML, phonegap, ...), изменить его размер и загрузить на веб-сайт.
Идеальная последовательность:
- Сфотографируй
- Загрузить фотографию в элемент img
- Изменить размер изображения (используя Pixastic)
- Загрузить его на веб-сайт
- Информирование пользователя об ошибке успеха
Все это было бы очень простой последовательной программой, если бы каждый шаг возвращал управление к следующему по завершении, но в действительности:
- Сделайте снимок асинхронным, поэтому программа пытается загрузить его в элемент img до того, как он появится
- Загрузка фотографии выполняется асинхронно, поэтому изменение размера изображения начинается до полной загрузки IMG
- Изменение размера выполняется асинхронно, поэтому загрузка на веб-сайт начинается до полного изменения размера изображения
- Загрузка на веб-сайт выполняется асинхронно, поэтому программа продолжается до полной загрузки фотографии.
И, кстати, 4 из 5 шагов включают функции обратного вызова.
Мое решение, таким образом, заключается в том, чтобы вложить каждый шаг в предыдущий и использовать .onload и другие подобные уловки, это выглядит примерно так:
takeAPhoto(takeaphotocallback(photo) {
photo.onload = function () {
resizePhoto(photo, resizePhotoCallback(photo) {
uploadPhoto(photo, uploadPhotoCallback(status) {
informUserOnOutcome();
});
});
};
loadPhoto(photo);
});
(надеюсь, я не совершил слишком много ошибок, доводя код до необходимого, реальная вещь слишком отвлекает)
Я считаю, что это идеальный пример, когда асинхронность не годится, а синхронизация хороша, потому что в отличие от обработки событий в пользовательском интерфейсе, мы должны завершить каждый шаг до того, как будет выполнен следующий, но код - русская кукольная конструкция, это сбивает с толку и нечитабельности, трудно добиться повторного использования кода, потому что из-за всей вложенности просто трудно передать во внутреннюю функцию все необходимые параметры, не передавая их в каждый контейнер по очереди или не используя злые глобальные переменные, и я бы хотел, чтобы результат всего этого кода даст мне код возврата, но первый контейнер будет завершен задолго до того, как код возврата станет доступен.
Теперь вернемся к первоначальному вопросу Тома, каким было бы умное, простое для чтения, легкое в повторном использовании решение для того, что было бы очень простой программой 15 лет назад с использованием, скажем, C и тупой электронной доски?
Требование на самом деле настолько простое, что у меня сложилось впечатление, что я, должно быть, упускаю фундаментальное понимание Javsascript и современного программирования. Конечно, технология предназначена для повышения производительности, верно?
Спасибо за ваше терпение
Раймон Динозавр; -)