我有一种情况,我想要添加的值取决于未来的值,即
let metadata = {videoId: 123, likes: 400};
let addSubtitles = R.assoc('subtitles', R.__, R.__);
此处addSubtitles
是部分应用的功能。但是,addSubtitles
的第二个参数应该是字幕,但字幕本身依赖于第三个参数,即metadata.videoId
。如下调用:
addSubtitles(metadata); //but with another argument perhaps?
const subtitles = async getSubtitles(videoId) => await apiCall(videoId);
以功能方式解决这个问题的方法是什么?似乎我可以约束未来第三个论点的背景,但不确定如何去做这个。
如果有任何额外信息需要回答,请告诉我。
这是一个有效的解决方案,但我希望使用Ramda来完成这项工作:
const addSubs = async function(el) {¬
const subtitles = await writeCaptions(el.videoId);¬
return R.assoc('subtitles', subtitles, el);¬
};
答案 0 :(得分:2)
首先让我补充一下,注意您不需要在签名中使用R._
来获取以后的值。几乎Ramda库中的每个函数都是自动调用的,因此您可以调用所有参数或仅使用某个子集来预加载数据。 R._
仅用于为将来的呼叫保留空间。
所以你想要做的就是只要一次添加一个参数,直到你得到一个完整的函数准备好调用。如果订单有误,您可以使用R.flip
或R._
(取决于具体情况)来达到您准备填写的价值,然后回到您还不知道的价值。< / p>
因此,根据您的描述,您可能会担心getSubtitles(metadata)
是一个返回承诺的网络调用。这个例子将在这个假设下进行。在这里,我认为R.flip
比R._
更具表现力。
const metadata = { videoId: 123, likes: 400 }
const addSubtitles = R.flip(R.assoc('subtitles'))
// Now you have a curried function that takes 2 arguments, first the metadata, and then the subtitles.
const withSubtitlesPromise = getSubtitles(metadata)
// Here we drill down a little further by adding the metadata, and then
// pass it as the callback to .then, which will pass in the final param
// once it resolves
.then(addSubtitles(metadata)
withSubtitlesPromise.then(console.log)
您绝对可以在单个函数中捕获所有这些逻辑,该函数接收metadata
并返回字幕数据的承诺。为了更好地衡量,我们还将getSubtitles
作为依赖性传递,以便于测试和更弱的耦合。现在,换掉另一个用于检索字幕数据的功能是微不足道的。在这种情况下,使用R._
会使代码更清晰,因此我们会将其切换。
// Define all the logic in a single easy function
const makeAddSubtitles = getSubtitles => metadata =>
getSubtitles(metadata).then(R.assoc('subtitles', R._, metadata))
// Then push in the dependency
const addSubtitles = makeAddSubtitles(getSubtitles)
// Use it
const vid123 = { videoId: 123, likes: 400 }
const vid123WithSubsPromise = addSubtitles(vid123)