Обещание 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 быть завернуто в Error? для соответствующих обсуждений.

person Bergi    schedule 27.08.2015