Обещаване на API

Ако искам да обещая всички кодови пътища в myFunction, трябва ли да създам deferred вътре в myFunction?

function myFunction(options) {
  if(!options) {
    throw 'foo'; // But I want the API for myFunction to be promise-based...
  } 

  return promiseBasedApi.doSomethingAndReturnPromise();
}

person Ben Aston    schedule 27.08.2015    source източник


Отговори (2)


трябва ли да създам отложен вътре myFunction?

(Това е терминологията на jQuery, общият случай би бил „Трябва ли да създам обещание в моята функция?“)

Само ако вашата функция все още няма обещание, тя може да се върне; често го прави, ако изчаква да завърши каквато и да е асинхронна операция (ajax, някакъв друг базиран на обещание API и т.н.).


  if(!options) {
      throw 'foo'; // But I want the API for myFunction to be promise-based...
  }

Ако питате дали трябва да създадете обещание за отхвърляне за грешката, че options не е предоставена, не, не бих очаквал това от API. Има два аспекта на API на асинхронна операция:

  1. Посвещение

  2. Завършване

В горното, липсата на предоставяне на options е грешка по време на инициирането на заявката. Бих очаквал вградено изключение, а не обратно извикване на асинхронна грешка.

Грешки при обработката на заявката (HTTP грешки и т.н.) биха били грешки, които бих очаквал чрез механизма за отхвърляне на обещанието.

person T.J. Crowder    schedule 27.08.2015
comment
Всъщност използвам библиотеката q, така че я взех от там. Така че, ако искам напълно да обещая тази функция, тогава трябва да върна отхвърлено обещание в изключителния случай (throw foo;)? Знаете ли дали има стенограма за това в q? (Взето е повторно започване и завършване), но този въпрос все още стои.) - person Ben Aston; 27.08.2015
comment
@BenAston: Най-добре е да споменете или маркирате, ако използвате конкретна библиотека. Моето мнение е, че не е необходимо да връщате отхвърлено обещание за горното; Бих хвърлил изключение, както правите вие ​​(вижте втората половина на отговора ми, който може би съм добавил, докато пишете коментара си). Страхувам се, че не мога да помогна със спецификата на библиотеката Q, но повечето библиотеки за обещания имат средство за създаване на отхвърлено обещание. - person T.J. Crowder; 27.08.2015
comment
Концепцията за начало срещу завършване. Това ваша идея ли е или от книга (ако да, коя)? - person Ben Aston; 27.08.2015
comment
@BenAston: Не мисля, че съм си го измислил, но не е и от книга. Това е просто естеството на асинхронната обработка: Иницииране, Обработка, Завършване. Само първият и последният наистина имат присъствие на API. :-) - person T.J. Crowder; 27.08.2015
comment
Това е терминологията на jQuery - за да бъда честен, не само jQuery. Някои други библиотеки предлагат отложени. Q е една такава библиотека. - person Roamer-1888; 29.08.2015
comment
@Roamer-1888: Да -- вижте коментара на Бен по-горе. - person T.J. Crowder; 29.08.2015

Не, нямате нужда от отложен или Promise конструктор във вашата функция. Нуждаете се от тези само за API, които не са базирани на обещание. Дори тогава трябва да не го използвате глобално, а отделна възможност за обещание за всеки път на асинхронен код.

Във вашия случай трябва просто да върнете отхвърлено обещание, вместо да хвърляте:

function myFunction(options) {
  if (!options) {
    return Promise.reject(new FooError()); // as promised!
  } 

  return promiseBasedApi.doSomethingAndReturnPromise();
}

Алтернатива, ако използвате Bluebird, би била да обвиете функцията за връщане на хвърляне или (обещание) в Promise.method. Вижте също Трябва ли някога асинхронен API да хвърля синхронно? и Трябва ли съобщение Promise.reject да бъде обвито в грешка? за свързани дискусии.

person Bergi    schedule 27.08.2015