Javascript 使用Ramda处理承诺和等待

Javascript 使用Ramda处理承诺和等待,javascript,arrays,json,ramda.js,Javascript,Arrays,Json,Ramda.js,我有一段代码是用Lodash编写的: 持续利润= 价格- _萨姆比先生( 等待承诺( 映射(uOrder=>uOrder.invoice,wait order.upstreamers), ), “金额”, ); 我想使用Ramda对其进行更改,在思考并阅读了一些文档后,我写了以下内容: const result=R.compose( R.pick(['amount']), 等待承诺。所有(), R.map(等待订单、上游订单、订单、发票), ); 当然,这是错误的,也不起作用,但这是我的第一

我有一段代码是用Lodash编写的:

持续利润= 价格- _萨姆比先生( 等待承诺( 映射(uOrder=>uOrder.invoice,wait order.upstreamers), ), “金额”, ); 我想使用Ramda对其进行更改,在思考并阅读了一些文档后,我写了以下内容:

const result=R.compose(
R.pick(['amount']),
等待承诺。所有(),
R.map(等待订单、上游订单、订单、发票),
);
当然,这是错误的,也不起作用,但这是我的第一种方法,我想知道如何以一种功能性的方式完美地使用Ramda来处理这种情况。我怎样才能做到这一点

对象的顺序也是以下示例的数组:

    { 
    "_id" : ObjectId("59dce1f92d57920d3e62bdbc"), 
    "updatedAt" : ISODate("2017-10-10T15:06:34.111+0000"), 
    "createdAt" : ISODate("2017-10-10T15:06:33.996+0000"), 
    "_customer" : ObjectId("59dce1f92d57920d3e62bd44"), 
    "_distributor" : ObjectId("59dce1f92d57920d3e62bd39"), 
    "status" : "NEW", 
    "cart" : [
        {
            "count" : NumberInt(1), 
            "_item" : ObjectId("59dce1f92d57920d3e62bd57"), 
            "_id" : ObjectId("59dce1f92d57920d3e62bdc1")
        }, 
        {
            "count" : NumberInt(1), 
            "_item" : ObjectId("59dce1f92d57920d3e62bd5c"), 
            "_id" : ObjectId("59dce1f92d57920d3e62bdc0")
        }, 
        {
            "count" : NumberInt(1), 
            "_item" : ObjectId("59dce1f92d57920d3e62bd61"), 
            "_id" : ObjectId("59dce1f92d57920d3e62bdbf")
        }, 
        {
            "count" : NumberInt(1), 
            "_item" : ObjectId("59dce1f92d57920d3e62bd66"), 
            "_id" : ObjectId("59dce1f92d57920d3e62bdbe")
        }, 
        {
            "count" : NumberInt(1), 
            "_item" : ObjectId("59dce1f92d57920d3e62bd6b"), 
            "_id" : ObjectId("59dce1f92d57920d3e62bdbd")
        }
    ], 
    "_upstreamOrders" : [
        "4545643499"
    ], 
    "key" : "4592846350", 
    "__v" : NumberInt(1), 
    "_invoice" : "0811260909610702"
}

我认为这将是一个很好的开始,可以分解原始函数到底在做什么

const profit =
  price - // subtract the result
  _.sumBy(
    await Promise.all(
      // Wait for upstreamOrders to resolve, and grab the 'invoice'
      // key for each
      map(uOrder => uOrder.invoice, await order.upstreamOrders),
    ),
    // calculate the sum of the invoices, based on the 'amount' key
    'amount',
  );
考虑到这一点,我们可以分解这些步骤,并将计算(同步)与数据(异步)分开

Ramda没有一个
sumBy
,因为我们可以从其他函数组合它。如果您将其分解,我们所做的是在两个不同的位置获取
发票
金额
,但我们可以使用

map(path(['invoice', 'amount']))
我们可以把它与
求和
减法
放在一起,创建一个完全独立于异步代码的函数

const calculateProfits = (price, orders) => compose(
  subtract(price),
  sum,
  map(path(['invoice', 'amount'])),
)(orders)
允许我们做一些类似的事情:

const profit = calculateProfits(price, await order.upstreamOrders)
或者如果
calculateProfits
是curry(我不知道上游者是如何工作的,是不是一个getter返回了一个承诺?)

最后,关于最初尝试的几点注意事项

const result = R.compose(
  R.pick(['amount']),

  // Promise.all is being called without any arguments
  // it doesn't really fit within `compose` anyway, but if we were
  // feeding an array of promises through, we'd want to just
  // put `Promise.all,`
  await Promise.all(),

  // the arguments here should be the other way around, we're
  // mapping over upstreamOrders, and the data comes last
  // uOrder isn't available in this scope, previously it was
  // `uOrder => uOrder.invoice`,
  // invoking a function and returning the invoice for that order
  R.map(await order.upstreamOrders, uOrder.invoice),
);

我认为这将是一个很好的开始,可以分解原始函数到底在做什么

const profit =
  price - // subtract the result
  _.sumBy(
    await Promise.all(
      // Wait for upstreamOrders to resolve, and grab the 'invoice'
      // key for each
      map(uOrder => uOrder.invoice, await order.upstreamOrders),
    ),
    // calculate the sum of the invoices, based on the 'amount' key
    'amount',
  );
考虑到这一点,我们可以分解这些步骤,并将计算(同步)与数据(异步)分开

Ramda没有一个
sumBy
,因为我们可以从其他函数组合它。如果您将其分解,我们所做的是在两个不同的位置获取
发票
金额
,但我们可以使用

map(path(['invoice', 'amount']))
我们可以把它与
求和
减法
放在一起,创建一个完全独立于异步代码的函数

const calculateProfits = (price, orders) => compose(
  subtract(price),
  sum,
  map(path(['invoice', 'amount'])),
)(orders)
允许我们做一些类似的事情:

const profit = calculateProfits(price, await order.upstreamOrders)
或者如果
calculateProfits
是curry(我不知道上游者是如何工作的,是不是一个getter返回了一个承诺?)

最后,关于最初尝试的几点注意事项

const result = R.compose(
  R.pick(['amount']),

  // Promise.all is being called without any arguments
  // it doesn't really fit within `compose` anyway, but if we were
  // feeding an array of promises through, we'd want to just
  // put `Promise.all,`
  await Promise.all(),

  // the arguments here should be the other way around, we're
  // mapping over upstreamOrders, and the data comes last
  // uOrder isn't available in this scope, previously it was
  // `uOrder => uOrder.invoice`,
  // invoking a function and returning the invoice for that order
  R.map(await order.upstreamOrders, uOrder.invoice),
);

wait
是关键字,不是可以组合的函数。您需要将其分解为
,然后
,并明确地使用承诺。您最多可以使用.TBH,我不明白您为什么要使用
compose
,表达式
wait Promise.all(R.map(uOrder=>uOrder.invoice,wait order.upstreammorders))
wait是关键字,不是可以组合的函数。您需要将其分解为
,然后
,并明确地使用承诺。您最多可以使用.TBH,我不明白您为什么要使用
compose
,表达式
wait Promise.all(R.map(uOrder=>uOrder.invoice,wait order.upstreamers))
。回答得很好,谢谢。你认为我应该如何完美地学习拉姆达?我用它编码了一个月,但仍然有麻烦\不要担心学得很好——根本没有这回事!不过,有一件事可能有助于学习,那就是将问题分解为它们的组成部分。在本例中,它将数据获取和转换分离,并单独测试
compose
中的每个函数并构建它。当我回答时,我打开了ramdajs.com/repl/以获得快速反馈并关注具体问题。我绝对建议您熟悉文档和这两个wiki页面。如果您能够尝试并理解这些示例为什么有效,那就更好了!ramda博客系列中的想法也很棒,最重要的一点也是,其中一些功能是ramda的一部分,但总体而言,这些想法要比ramda大得多。尝试其他fp库、教程甚至语言!回答得很好,谢谢。你认为我应该如何完美地学习拉姆达?我用它编码了一个月,但仍然有麻烦\不要担心学得很好——根本没有这回事!不过,有一件事可能有助于学习,那就是将问题分解为它们的组成部分。在本例中,它将数据获取和转换分离,并单独测试
compose
中的每个函数并构建它。当我回答时,我打开了ramdajs.com/repl/以获得快速反馈并关注具体问题。我绝对建议您熟悉文档和这两个wiki页面。如果您能够尝试并理解这些示例为什么有效,那就更好了!ramda博客系列中的想法也很棒,最重要的一点也是,其中一些功能是ramda的一部分,但总体而言,这些想法要比ramda大得多。尝试其他fp库、教程甚至语言!