Page 242 - Браун Э. - Изучаем JavaScript. Руководство по созданию современных веб-сайтов - 2017
P. 242

Одно из преимуществ сцепления обязательств в том, что вы не обязаны обраба­
       тывать ошибки на каждом этапе; если где-нибудь в цепочке произойдет ошибка, то
       цепочка остановится и управление перейдет к обработчику catch. Давайте заменим
                       1
       обратный отсчет  5 -секундным суеверным обратным отсчетом; вы обнаружите, что
       функция launch никогда не будет вызвана.

       Предотвращение незавер            ш е н н  ых обязательств
          Обязательства могут упростить ваш асинхронный код и защитить вас от проблем
       функций обратных вызовов,  вызываемых  несколько раз,  но они не защищают  вас
       от проблемы обязательств, которые никогда не завершаются ( т.е. когда вы забываете
       вызвать resol ve или rej ect). Ошибки этого вида может быть очень трудно обнару­
       жить, поскольку никакой ошибки нет . .   а в сложной системе незавершенное обяза­
                                          .
       тельство может быть просто потеряно.
          Один  из  способов  предотвращения  этого  заключается  в  определении  периода
       для обязательств; если обязательство не завершено за некий разумный период вре­
       мени, оно автоматически отклоняется. Вполне очевидно, что это вам решать, каков
       "разумный период времени''. Если у вас достаточно сложный алгоритм, выполнение
       которого предположительно займет 10 минут, не устанавливайте 1 - секундный период.
          Давайте вставим в нашу функцию launch искусственный отказ. Скажем, наша ра­
       кета очень экспериментальная, и она отказывает приблизительно в половине случаев.
       function  launch { )    {
           return  new  Promise { function ( r esolve,  rej ect )  {
               i f {Math . random { )   <  0 . 5 )   return ;  / /   отказ  ракеты
               console . l og { " П oexaл ! " ) ;
                                 и
               setTimeout { function  )    {
                                 {
                   resolve { " Ha  орбите ! " ) ;
               } ,   2 * 1 0 0 0 ) ;    / /  действительно  очень  быстрая  ракета
           } ) ;

          Способ  отказа в данном примере не очень достойный: мы не вызываем функцию
       rej ect и даже ничего не выводим на консоль. Мы просто тихо выходим в половине
       случаев. Если запустить этот пример несколько раз, то можно увидеть, что иногда он
       срабатывает, а иногда нет". безо всякого сообщения об ошибке, что явно нежелательно.
          Мы можем написать функцию, которая задает обязательству период.
       function  addTimeout { f n,  t i meout )  {
           i f { t i meout  ===  undefined)  t i meout  =  1 0 0 0 ;   / /   стандартный  период
           return  function { . . .   args )  {
               return  new  Promise { function ( r e solve ,  rej ect )  {
                   const  tid  =  setTimeout { r ej ect,  timeout ,
                      new  Еrrоr { "Истек  период  обязательства " ) )  ;
                   fn {  . .  . ar s )

                          g
                                                                 Обязательства   245
   237   238   239   240   241   242   243   244   245   246   247