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

algebraic implementation of $.when in Pacta.js

我正在写一个 nodejs 的东西,并尝试 Pacta promise library 来找乐子。 Pacta 的界面是 "algebraic,",但我对那个范式没有任何经验。

我想知道 "Pacta way" 是什么来完成与

相同的事情
$.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
}

也就是说,给定一个数组、一个 returns 承诺的迭代器函数和一个回调函数,我想将迭代器映射到数组并提供一个分辨率值数组(或拒绝原因)到所有承诺都已解决后的回调。

如果没有一种惯用的代数方式来表达这一点,我也很想知道。

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

Pacta's interface is "algebraic," but I don't have any experience with that paradigm.

ADTs 是表示嵌套数据类型的类型理论结构,例如 IntegerPromise。它们在函数式编程中大量使用,在这种风格中,您始终知道表达式和值的类型。没有不透明的隐式类型强制,只有显式类型强制。

这与 jQuery 的方法完全相反,$.when().then() 根据其参数的类型(和数量)做完全不同的事情。因此,翻译您的代码有点复杂。诚然,Pacta 没有最有用的实现,因此我们必须使用一些自己的辅助函数来完成此操作。

  • 假设您有一组(多个)承诺,并且您的 then 回调采用参数并且 return 是一个非承诺值:

    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
    });
    
  • 如果您的回调确实 return 承诺,请使用 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
    });
    

    如果您不知道 return 是什么,请使用 then 而不是 chain。如果你不知道它是什么 returns 并且想获得多个参数,请使用 .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]).…
    
  • 如果您的数组包含任何其他内容,即使 $.when 也不会如您所愿。

当然,根本不支持使用多个值解析的承诺 - 请改用数组。此外,您的回调只会在所有承诺 fulfilled 时被调用,而不是在它们 settled 时被调用,就像 jQuery 那样.