Нет абсолютно ничего плохого в хелпере, который создает deferred, если вы уверены, что вам действительно нужен deferred. За все время программирования промисов я нашел только одну ситуацию, когда мне действительно понадобился отложенный вызов, и я не мог просто реструктурировать свой код, чтобы использовать типичный шаблон конструктора промисов.
Кажется, ситуация, которую я обнаружил, и та, на которую указывали другие, возникает, когда у вас есть разделение между кодом, который создает обещанный/отложенный объект, и кодом, который разрешает или отклоняет его. Обычно они у вас есть вместе, но бывают случаи, когда это совершенно разные участки кода и есть логические причины делать это именно так. В таких случаях отложенный объект, построенный на основе обычного промиса, может быть более чистым методом реализации.
Вот еще одна простая реализация Deferred, которая также совместима как с предыдущими, так и с предыдущими версиями:
Почему конструктору Promise нужен исполнитель?
Но разве это плохая практика?
Я знаю, что есть некоторые пуристы, которые думают, что вы никогда не должны этого делать. Но я бы сказал, что это отличная практика, если вы уверены, что это самый чистый и простой способ реализации вашего кода и что его реализация с помощью типичного обратного вызова исполнителя конструктора Promise не так практична. Есть те, кто хочет использовать deferred, даже не попробовав и не изучив конструктор/исполнитель промисов, и это не будет хорошей практикой. По ряду причин следует использовать конструктор промисов, когда это целесообразно.
Одна из важных причин, по которой конструктор промисов предпочтительнее, заключается в том, что весь специфичный для промисов код в функции обратного вызова исполнителя "безопасен для бросков". Если в этом коде возникнет исключение, оно будет автоматически перехвачено и отклонено обещание (что хорошо). Если вы используете deferred и у вас есть куча кода, который манипулирует обещанием вне этого обратного вызова, он автоматически не становится безопасным. На самом деле, ваш код может даже генерировать синхронно, что является кошмаром для защиты от вызывающих. Вы можете увидеть описание этой проблемы здесь: https://stackoverflow.com/a/37657831/816620. Таким образом, отложенный шаблон не является предпочтительным, но при надлежащей защите все еще есть некоторые случаи (обычно редкие), когда он приводит к более чистой реализации.
Есть ли признанный, лучший образец?
Практически тот же ответ, что и выше. Предпочтение состоит в использовании конструктора/исполнителя промисов, но в ситуациях, когда это нецелесообразно (обычно когда разные участки кода создают промис, а затем разрешают/отклоняют его) и нет простого способа реорганизовать код, чтобы он хорошо работал с конструктор/исполнитель обещания, то отложенный объект, вероятно, является предпочтительной реализацией. Как правило, такие ситуации встречаются редко, потому что большую часть времени вы можете структурировать свой код так, чтобы один и тот же фрагмент кода создавал и разрешал/отклонял обещание, и вам не нужен отложенный.
Что такое идиоматический эквивалент TaskCompletionSource в JavaScript?
В Javascript нет встроенного эквивалента. Таким образом, вам придется создавать свои собственные, и кажется, что промисы — естественный способ сделать это, поскольку они естественным образом созданы для сигнализации о завершении или ошибке. Вам нужно будет показать нам свой фактический код, чтобы мы могли высказать мнение о том, можно ли реализовать вашу конкретную ситуацию без использования отложенного объекта.
person
jfriend00
schedule
01.08.2016