Каковы преимущества Promises над CPS и продолжением Functor/Monad?

ES6 Promises

ES6 Promises являются конечными машинами и, следовательно, требуют сложных реализаций. Помимо того, что Promise/A + spec поставляется с множеством грубых краев:

  • перегружен then (карта/цепочка)
  • рекурсивная сглаживающая/затем-ассимиляция
  • автоматический подъем
  • несколько подписчиков (многоадресная рассылка)
  • ожидаемая оценка

Распределение многоадресной рассылки и нетерпеливая оценка, среди прочего, причины, по которым ES6 Promises не могут быть отменены. Кроме того, мы не можем добавлять собственные слои then-ables с определенными функциями, потому что они сразу же ассимилируются рекурсивным выравниванием.

Я уверен, что было много веских причин для любого из этих проектных решений. Однако теперь у нас есть неизменная функция основного языка, а не конкретные конкурирующие DSL для асинхронных потоков управления в пользовательской среде. Разумеется, interop очень важен, но также способна развивать асинхронные функции управления потоком без необходимости учитывать обратную совместимость всего языка.

Стиль прохождения продолжения

Продолжение абстрагирования стилей прохождения из асинхронных потоков управления, поскольку оно избавляется от оператора return. Чтобы восстановить композиционную способность, нам нужен только функтор в контексте продолжений:

const compk = (f, g) => x => k => f(x) (x => g(x) (k));


const inck = x => k => setTimeout(k, 0, x + 1);

const log = prefix => x => console.log(prefix, x);


compk(inck, inck) (0) (log("async composition:")); // 2

Ответ 1

Недостатком любого подхода, который зависит от функционального состава, является то, что идиоматические кодовые последовательности JavaScript заменяются списками названных функций. Promises сами страдают от этого.

например. Я вижу, что люди делают то, что я называю callback lite:

let foo = () => Promise.resolve().then(() => console.log('foo'));
let bar = () => Promise.resolve().then(() => console.log('bar'));

foo().then(bar);