繁体   English   中英

纯函数可以返回一个随机时间后解析的承诺吗?

[英]Can a pure function return a promise that resolves after a random amount of time?

我知道这个例子很做作,但我仍然很好奇或者不是这可以被认为是一个纯粹的功能:

const addAsync = (x, y) => new Promise((resolve, reject) => {
    setTimeout(
        () => resolve(x + y),
        Math.random() * 1000
    );
});

每次调用此函数都会返回一个Promise,该Promise解析为两个参数的总和。 承诺在0到1秒之间的随机时间后解决。

对于所有的目的和目的,这似乎是完全纯粹的,这意味着我可以在测试中或在我的代码中将此函数视为纯函数(a, b) -> Promise(a + b) 但是,由于我们使用的是Math.random() ,因此我们无法将此函数转换为查找表并返回而不会丢失功能(我们会丢失延迟)。 那么这可以被认为是纯粹的吗?

我相信它可以被认为是一个纯粹的功能。 纯函数定义为一种函数,其中返回值仅由其输入值确定,没有可观察到的副作用。

在这种情况下,输出仅由其输入确定,并且不会产生任何副作用。 计算结果需要不同时间的事实不应影响其纯度。

但我会警告我不是函数式编程专家,我可能错了

让我们首先澄清纯粹一词。 纯度意味着参考透明度,即。 一个人可以用其评估结果替换表达式而不改变程序的行为。 这是一个返回承诺的动作。 为了可视化计算,我执行记录作为副作用:

 const addAsync = (x, y) => new Promise((r, e) => { setTimeout( z => (console.log(z), r(z)), Math.random() * 1000, x + y ); }); console.log("before"); addAsync(2, 3); console.log("after"); // logs "before" "after" 5 

接下来,我将表达式addAsync(2, 3)替换为其结果,该结果是包含5已实现Promise 由于Javascript中没有Promise文字,我用Promise.resolve表示已经解决的承诺:

 console.log("before"); Promise.resolve(console.log(5), 5); console.log("after"); // logs "before" 5 "after" 

看代码似乎没什么区别。 表达式addAsync(2, 3)产生一个固定的承诺(类似于Promise(5) )。 Promise.resolve(console.log(5), 5)代表了这个非常稳定的承诺。 但是通过观察console.log副作用,我们可以看到评估顺序已经改变,这是一个返回promise的函数实际上改变了程序的行为。 因此,这种功能是不纯的。

没有。

我认为返回的诺言所处的状态对我们来说是未知的,就像施罗丁格猫生命一样。 Promise要么已经解决,要么被拒绝或待决,但是我们无法预测它何时处于什么状态。 一个概述了这个的片段:

 let a = 0;
 addAsync(1,2).then(res => a += res).then(console.log);
 addAsync(0, 1).then(res => a += res).then(console.log);

如果addAsync是纯粹的,它将始终记录相同。

简单的答案是否定的。 但我提供了一种简单的方法来将杂质推到别处

在代码的纯粹部分

const incRandomDelay = addAsync.bind(null,1)

现在在代码的效果部分的某个地方

incRandomDelay(10).then( sum => writeToFile(sum) )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM