Fluture:将未来转换回对快速全局错误处理的承诺

Fluture: converting a future back to a promise for express global error handling

我正在尝试找到一种方法,使用 fluture 库将 Promise 转换为 future 以实现函数式编程,使用函数式管道转换数据,然后转换回 Promise,这样我就可以利用 await/async 功能。这是一个快速应用程序,我正在使用全局错误处理,如果我在未来的流程中发现错误而没有在未来处理完成后转换为承诺,我看不到如何利用端点的全局错误处理。

  1. 我这样想对吗?
  2. 如果是这样,我如何在调用 encaseP 和后续管道代码后使用下面代码中的 promise 实用程序转换回 promise?
  3. 有没有更好的方法来利用未来的管道,同时仍然向全局错误处理程序发送错误?
  4. 此外,如果我确实转换为承诺,如果我使用 await,我是否也可以在将来访问实际值,我想是吗?

抱歉,如果这是一个不好的问题,我是函数式编程和 fluture 的新手,我正在努力让我的鸭子保持正确的对齐方式。

const arrayList = [];
arrayList.push({
    a: {
        b: 1,
        c: 2,
        d: 3
    }
},{
    a: {
        b: 2,
        c: 3,
        d: 3
    }
})

const findData = (arrayList) => Promise.reject(null)

let total1 = (list) => encaseP(findData)(list)
    .pipe(res => res)
    .pipe(map(x => x.map(y => ({
        a: {
            b: y.a.b + 1,
            c: y.a.c + 1,
            d: y.a.d + 1
        }
    }))))
    .pipe(promise (() => {console.log('do nothing')}) (console.log));


console.log(total1);
total1(arrayList);

当我 运行 上述代码时,出现以下错误:

internal/modules/cjs/loader.js:992 internalBinding('errors').triggerUncaughtException( ^

TypeError: promise() 期望它的第一个参数是一个有效的 Future。

我相信我已经充分回答了这个问题in Gitter。我将在下面总结我的回复以供将来参考。


我在您的代码中看到了一些我想解决的问题:

  1. findData:我建议尽早用 encaseP 包装它。所以你会得到 (arrayList) => encaseP (Promise.reject) (arrayList),它也可以写成 encaseP (Promise.reject)(因为输入参数只是按原样传递)。
  2. total1 函数现在可以直接调用 findData 并返回 Future。
  3. .pipe (res => res):这一行实际上什么也没做。在这里,您将 res(数组的 Future)转换为 res,这完全是同一回事。重要的是要了解管道只是函数应用程序:
  4. .pipe (promise (() => {console.log('do nothing')}) (console.log)):当你消费一个 Future 时,工作真正开始并且消费 returns 一个取消函数(或者一个 Promise,在 promise (future) 的情况下)。您不应该在函数内部执行此操作,而应在函数外部执行此操作。我推荐阅读 introduction to Fluture, especially the part about "not consuming futures"。一个指导性的经验法则是,您应该只看到在程序的“边缘”调用的 fork(或 promise 或任何其他消费函数)。那就是你不可能将 Future 进一步传递给理解它的一方的地步。

total1 函数中删除最后一行后,Future 不会被消耗,而是从函数返回,我们可以在需要的地方消耗 Future。例如,运行 total1 函数并将其输出转发到 Response 的 Express 中间件看起来像:

app.get ('/total', (req, res, next) => {
  total1 (req.query.arrayList)
  .pipe (fork (next) (result => res.json ({result})))
})

next 作为拒绝回调传递给 fork 会导致 Express 处理错误。对于您想要在内部使用 Future 来控制异步的每条快速路由,这都是必需的。您可以使用 fluture-express 删除一些样板文件。