Разница между defer(). Обещанием и обещанием

Я знаю, что defer разделяет состояния и управление состояниями обещаний, здесь, на примере Q, обещание, возвращаемое Q.defer().promise а также Q.Promise совершенно другой, почему проектирование таким образом? и какая разница между этими двумя "обещаниями"

заранее спасибо

PS: в настоящее время я работаю над библиотекой Promise, выпуск и PRS приветствуются: https://github.com/XiaomingJS/Xiaoming.Promise

1 ответ

Решение

Ну, это про источник разрешения обещания. Q и множество других библиотек предлагают два API:

  • Наследие defer API - в котором вы создаете отложенное, что вы можете .resolve(value) и у него есть обещание, которое вы можете вернуть.
  • Конструктор обещаний - это современный API, в котором вы создаете обещание из источника завершения.

Примерно занимаюсь:

var d = Q.defer();
setTimeout(function(){ d.resolve(); }, 1000); 
return d.promise;

Такой же как:

return new Promise(function(resolve, reject){
   setTimeout(resolve, 1000);
});

так что вы можете спросить

Зачем нам нужны два API?

Ну, API отложений пришел первым. Это то, как с этим справляются некоторые другие языки, это то, как с этим справляются газеты, и то, как люди использовали его первыми - однако - между этими двумя API есть важное различие. Конструктор обещаний безопасен.

Брось безопасность

Обещает абстрактную обработку исключений и безопасен. Если вы добавите в цепочку обещаний, это исключение преобразуется в отказ, цитируя спецификацию:

Если onFulfilled или onRejected выбрасывают исключение e, promise2 должно быть отклонено с e в качестве причины

Давайте предположим, что вы анализируете JSON из XHR-запроса:

function get(){
    var d = Q.defer();
    if(cached) { // use cached version user edited in localStorage
        d.resolve(JSON.parse(cached));
    } else { // get from server
       myCallbackApi('/foo', function(res){ d.resolve(res); });
    }
}

Теперь давайте посмотрим на версию конструктора обещаний:

function get(){
    return new Promise(function(resolve, reject){ 
        if(cached) { // use cached version user edited in localStorage
            resolve(JSON.parse(cached));
        } else { // get from server
           myCallbackApi('/foo', resolve);
        }
    });
}

Теперь предположим, что каким-то образом ваш сервер отправил вам недействительный JSON (или пользователь отредактировал его в недопустимое состояние), и вы его кэшировали.

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

try{
  return get().catch(function(e){
     return handleException(e); // can also just pass as function
  });
} catch(e){ 
   handleException(e);
}

В нижней версии - конструктор обещаний преобразует throw С отклонениями, так что достаточно сделать:

return get().then(function(e){
   return handleException(e);
});

Предотвращение появления целого класса ошибок программиста.

Другие вопросы по тегам