Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Logging 如何在避难所/Fluture中正确登录? 背景_Logging_Functional Programming_Sanctuary_Fluture - Fatal编程技术网

Logging 如何在避难所/Fluture中正确登录? 背景

Logging 如何在避难所/Fluture中正确登录? 背景,logging,functional-programming,sanctuary,fluture,Logging,Functional Programming,Sanctuary,Fluture,我有一个函数,名为loginfoancy。让我们考虑一下这个函数通过网络向日志服务器发送一些信息。出于这个问题的目的,让我们假设函数实现如下: const logInfoAsync = logger => message => new Promise( ( resolve, reject ) => { setTimeout( () => { //random fail reason. if( mess

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

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 );
    })
用法:

const myLog= logInfoAsync( console.log );
myLog("Hello world!") // Rejected: "We have angered the Gods. Message is too big!"
myLog("Hello") // Resolved: "Hello"
问题 到目前为止还不错。我们有一个标准的记录器,有时工作,有时它激怒了神

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

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
s

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

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

问题 因此,鉴于这个片段,我有以下问题:

  • 如果日志失败,您将如何保持链运行
  • 您如何使日志故障和恢复对应用程序不可见(而不使用(
    try/catch
    )之类的等效工具
  • 日志最常用的模式是什么

  • 我会专门为期货制作一个
    tap
    功能,例如:

    const always = x => y => x
    const tapF = f => x => f(x).fold(always(x), always(x))
    
    tapF
    的这个实现期望
    f
    返回一个未来,它将强制它使用原始输入值进行解析

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

    request.get("http://mywebsite.com")
    .chain( tapF(res => myLogF(`res is: ${res}`)) )
    .chain( saveDB )
    .chain( tapF(() => myLogF("Saved!")) )
    
    现在,这个表达式的结果完全独立于
    tapF
    函数内部发生的事情

    我相信这应该能回答你的前两个问题。最后一个问题:“日志最常用的模式是什么?”我不确定。有几种模式,我可以想到两种:

    • 在表示副作用的Monad中作为副作用登录。这就是我们使用
      tapF
      所做的
    • 使用Writer Monad在内存中收集日志,并在程序边缘写入日志。我没有这种方法的经验

    但是,如果
    myLogF
    无法运行,会发生什么情况呢?同样,在这种情况下,
    myLogF
    的执行将非常紧迫。有没有办法让它变得懒惰(只有在将来运行时才记录)或者根本没有意义?