首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确登录圣所/弗劳尔?

如何正确登录圣所/弗劳尔?
EN

Stack Overflow用户
提问于 2018-07-26 08:37:24
回答 1查看 264关注 0票数 2

背景

我有一个函数,叫做logInfoAsync。让我们考虑一下这个函数通过网络向日志服务器发送一些信息。为了这个问题的目的,让我们假设函数的实现方式如下:

代码语言:javascript
复制
const logInfoAsync = logger => message =>
    new Promise( ( resolve, reject ) => {
        setTimeout( () => {
            //random fail reason.
            if( message.length > 10 ){ 
                reject( "We have angered the Gods. Message is too big!" );
                return;
            }
            logger(message);
            resolve();
        }, 2000 );
    })

用法:

代码语言:javascript
复制
const myLog= logInfoAsync( console.log );
myLog("Hello world!") // Rejected: "We have angered the Gods. Message is too big!"
myLog("Hello") // Resolved: "Hello"

问题

到目前一切尚好。我们有一个标准的记录器,有时起作用,有时会激怒神。

现在,让我们假设我们有一系列连续的async计算:

代码语言:javascript
复制
const { Future } = require("Fluture");

const myLogF= Future.encaseP( logInfoAsync( console.log ) );

//request.get returns a Future and so does saveDB
request.get("http://mywebsite.com")
    .chain( response => myLogF(`res is: ${res}`) )
    .chain( saveDB )
    .chain( ( ) => myLogF("Saved!") )
    .fork(
        err => console.log(`Something failed badly!: ${err}`),
        ( ) => console.log("Data saved to Olympus with great success!")
    );

在这个例子中,如果伐木者激怒了上帝,会发生什么?我们没能保存数据!也许请求进行得很好,也许数据是有效的,但是因为记录器失败了,我们就完蛋了!

研究

现在,一个可能的解决方案是在每个日志之后使用Fluture.bimap。这太可怕了。

我不希望我的日志比它们更具有侵略性,而且我肯定不会用承诺样式的try/catch来乱扔我的代码。

不幸的是,这是我唯一能想到的.我认为最好的选择是备份记录器,例如,在console.error失败时使用的myLogF,但理想情况下,我希望它是不可见的。

应用程序不应该知道它正在被记录!

问题

因此,考虑到这个片段,我有以下问题:

  1. 如果日志发生故障,您将如何保持链的正常运行?
  2. 如何使日志失败和恢复对应用程序不可见(而不使用相当于( try/catch )的垃圾)?
  3. 最常用的日志模式是什么?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-26 11:50:40

我会专门为期货做一个tap函数,例如:

代码语言:javascript
复制
const always = x => y => x
const tapF = f => x => f(x).fold(always(x), always(x))

tapF的这个实现期望f返回一个未来,它将强制它使用原始的输入值进行解析。

然后,它可以用于日志记录,例如:

代码语言:javascript
复制
request.get("http://mywebsite.com")
.chain( tapF(res => myLogF(`res is: ${res}`)) )
.chain( saveDB )
.chain( tapF(() => myLogF("Saved!")) )

现在,这个表达式的结果完全独立于tapF函数内部发生的情况。

我认为这应该能回答你的前两个问题。最后一个;“日志最常用的模式是什么?”,我不太清楚。有几种模式,我能想到的有两种:

  • 作为一个副作用在Monad内进行日志记录,它表示副作用。这就是我们对tapF所做的。
  • 使用Writer收集内存中的日志,并将它们写入程序的边缘。我没有这种方法的经验。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51534507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档