在Pacta.js中代数实现$ .when

时间:2015-02-07 19:31:02

标签: javascript jquery node.js promise algebraic-data-types

我正在写一个nodejs的东西,并尝试Pacta promise library以获得乐趣。 Pacta的界面是“代数”,但我对这种范式没有任何经验。

我想知道完成与

相同的事情的“Pacta方式”是什么
$.when.apply(undefined, arrayOfThings)
.then(function onceAllThingsAreResolved(thing1Val, thing2Val, ...) {
    // code that executes once all things have been coerced to settled promises
    // and which receives ordered resolution values, either as 
    // separate args or as a single array arg
}

也就是说,给定一个数组,一个返回promise和迭代函数的迭代器函数,我想将迭代器映射到数组上,并为回调提供一个解析值(或拒绝原因)的数组一旦所有的承诺得到解决。

如果没有一种惯用的代数方式来表达这一点,我就会有兴趣知道这一点。

编辑:根据@Bergi更新使用$ .when来正确容纳数组。

1 个答案:

答案 0 :(得分:2)

  

Pacta的界面是"代数,"但我对这种范式没有任何经验。

ADTs是表示嵌套数据类型的类型理论构造,例如Promise的{​​{1}}。它们在函数式编程中被大量使用,你总是知道表达式和值的类型。没有不透明的隐式类型强制,但只有明确的强制。

这与jQuery的方法完全相反,Integer$.when()根据其参数的类型(和数量)完成不同的事情。因此,翻译代码有点复杂。不可否认,Pacta没有最有用的实现,所以我们必须使用一些自己的帮助函数来实现这一点。

  • 假设你有一个(多个)promise的数组,你的.then()回调接受参数并返回一个非promise值:

    then
  • 如果您的回调没有多个参数,请使用arrayOfPromises.reduce(function(arr, val) { return arr.append(val); }, Promise.of([])).spread(function (…args) { // code that executes once all promises have been fulfilled // and which receives the resolution values as separate args }); 代替map

    spread
  • 如果您的回调确实返回了承诺,请使用arrayOfPromises.reduce(function(arrp, valp) { return arrp.append(valp); }, Promise.of([])).map(function (arr) { // code that executes once all promises have been fulfilled // and which receives the resolution values as an array }); 代替chain

    map

    如果您不知道它返回的内容,请使用arrayOfPromises.reduce(function(arr, val) { return arr.append(val); }, Promise.of([])).chain(function (arr) { // code that executes once all promises have been fulfilled // and which receives the resolution values as an array }); 代替then。如果您不知道它返回的内容并希望获得多个参数,请使用chain

  • 如果您的数组包含与普通值混合的promise,请使用以下命令:

    .spread(…).then(identity)
  • 如果您的数组仅包含单个或不包含(不可用)值,请使用

    arrayOfThings.reduce(function(arrp, val) {
        var p = new Promise();
        Promise.resolve(p, val);
        return arrp.append(p);
    }, Promise.of([])).…
    
  • 如果您的数组包含其他任何内容,即使Promise.of(arrayOfThings[0]).… 也不会达到您的预期效果。

当然,根本不支持使用多个值解析的promise - 而是使用数组。此外,只有当所有承诺完成时才会调用您的回调,而不是当它们已完成时,就像jQuery执行此操作一样。