Включит ли javascript-файлы с сайта Google замедление загрузки?

@ Jordan во-первых, как отмечали комментаторы, при использовании отложенной библиотеки ваш первый пример определенно дает результат, который вы ожидаете:

promise1 rejected
promise2 rejected
promise3 rejected

Во-вторых, даже если он будет производить вывод, который вы предлагаете, это не повлияет поток выполнения вашего второго фрагмента, который немного отличается, больше напоминает:

promise.then(function(first_value) {
    console.log('promise1 resolved');
    var promise = db.put(first_value);
    promise.then(function (second_value) {
         console.log('promise2 resolved');
         var promise = db.put(second_value);
         promise.then(
             function (wins) { console.log('promise3 resolved'); },
             function (err) { console.log('promise3 rejected'); return err; });
    }, function (err) { console.log('promise2 rejected'); return err;});
}, function (err) { console.log('promise1 rejected'); return err});

и что в случае первого отклонения обещания будет просто выводиться:

promise1 rejected

Однако (попадая в самую интересную часть), хотя отложенная библиотека определенно возвращает 3 x rejected, большинство других библиотек обещаний вернут 1 x rejected, 2 x resolved (что приводит к предположению, что вы получили эти результаты, используя вместо этого другую библиотеку обещаний).

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

В синхронизирующей мировой копии «обещания отклонения» есть throw. Таким образом, семантически, синхронизация async deferred.reject(new Error()) равна throw new Error(). В вашем примере вы не бросаете ошибки в своих обратных вызовах синхронизации, вы просто возвращаете их, поэтому вы переключаетесь на поток успеха, причем ошибка является значением успеха. Чтобы убедиться, что отклонение передано дальше, вам нужно повторно выбросить свои ошибки:

function (err) { console.log('promise1 rejected'); throw err; });

Итак, теперь вопрос заключается в том, почему отложенная библиотека приняла возвращенную ошибку как отклонение?

Причина для этого, заключается в том, что отклонение в отложенных работах несколько отличается. В отложенном lib это правило: обещание отвергается, когда оно разрешено с экземпляром ошибки, поэтому, даже если вы deferred.resolve(new Error()), оно будет действовать как deferred.reject(new Error()), и если вы попытаетесь сделать deferred.reject(notAnError), это вызовет исключение, говорящее , это обещание может быть отклонено только с учетом ошибки. Это дает понять, почему ошибка, возвращаемая с then обратного вызова, отвергает обещание.

Существует некоторая обоснованная аргументация отложенной логики, но все же она не соответствует тем, как throw работает на JavaScript, и из-за этого это поведение запланировано для изменения с версией v0.7 отложенных.

Краткий обзор:

Чтобы избежать путаницы и неожиданных результатов, просто следуйте правилам хорошей практики:

  1. Всегда отклоняйте свои обещания с помощью экземпляров ошибок (следуйте правилам мира синхронизации, где значение выброса, которое не является ошибкой, считается плохой практикой).
  2. Отклонение от обратных вызовов синхронизации путем металирования ошибок (возврат их не гарантирует отклонения).

Повинуясь выше, вы получите как согласованные, так и ожидаемые результаты как в отложенных, так и в других популярных библиотеках обещаний.

1
задан Gazow 12 October 2010 в 06:33
поделиться