2017-10-12 2 views
0

J'ai un morceau de code qui écrit par lodash comme ci-dessous:En utilisant Ramda pour gérer la promesse et attendre

const profit = 
    price - 
    _.sumBy(
    await Promise.all(
     map(uOrder => uOrder.invoice, await order.upstreamOrders), 
    ), 
    'amount', 
); 

Je veux changer à Ramda, après quelques pensée et la lecture de certains Doc j'écris ci-dessous le code:

const resualt = R.compose(
    R.pick(['amount']), 
    await Promise.all(), 
    R.map(await order.upstreamOrders, uOrder.invoice), 
); 

bien sûr son mal et ne fonctionne pas, mais sa première approche de et je veux savoir comment gérer une telle situation, en utilisant parfaitement et Ramda de manière fonctionnelle. comment je peux effectuer cela? également commander l'objet est un tableau de exemple suivant:

{ 
"_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" 

}

+0

' await' est un mot-clé, pas une fonction qui peut être composée. Vous devez le concevoir en 'then' et travailler explicitement avec les promesses. Au mieux, vous pouvez utiliser ['composeP'] (http://ramdajs.com/docs/#composeP). – Bergi

+0

TBH, je ne vois pas pourquoi vous voudriez utiliser 'composer', il n'y a rien que vous ayez besoin de changer à propos de l'expression' await Promise.all (R.map (uOrder => uOrder.invoice, wait order.upstreamOrders)) ». – Bergi

Répondre

2

Je pense que ce serait un bon point de départ pour décomposer exactement ce que la fonction d'origine fait

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', 
); 

Avec cette en gardant à l'esprit que nous pouvons décomposer ces étapes et séparer les calculs (synchrones) des données (asynchrones)

Ramda n'a pas de sumBy, car nous pouvons composer cela à partir d'autres fonctions. Si vous le décomposer, ce que nous avons fait était saisir le invoice et la amount en deux endroits séparés, mais nous pouvons tout simplement prendre un tableau des montants avec

map(path(['invoice', 'amount'])) 

Et nous pouvons laisser tomber qu'à côté d'un sum et subtract pour créer une fonction qui est tout à fait indépendant de notre code async

const calculateProfits = (price, orders) => compose(
    subtract(price), 
    sum, 
    map(path(['invoice', 'amount'])), 
)(orders) 

Ce qui nous permet de faire quelque chose comme:

const profit = calculateProfits(price, await order.upstreamOrders) 

Ou si calculateProfits était cari (et je ne sais pas comment fonctionne upstreamOrders, est un getter qui retourne une promesse?)

const getUpstreamOrders = order => order.upstreamOrders 

getUpstreamOrders(order) 
    .then(calculateProfits(price)) 
    .then(profits => { 
    // Do what you want with the profits 
    }) 

Enfin, quelques notes sur la première tentative

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), 
); 
+0

Bonne réponse, merci. comme votre opinion comment je devrais apprendre ramda parfaitement? je code avec elle abotut 1 mois mais j'ai encore des problèmes! \ – amir

+0

Ne vous inquiétez pas de l'apprendre parfaitement - il n'y a pas une telle chose! Une chose qui pourrait aider à apprendre est cependant de diviser les problèmes en leurs parties constituantes. Dans ce cas, il s'agissait de séparer la récupération de données et les transformations, ainsi que de tester chaque fonction dans le 'composer' individuellement et de le construire. Quand je répondais, j'ai lancé le ramdajs.com/repl/ pour avoir un retour rapide et me concentrer sur le problème spécifique. –

+0

Je recommande vivement de vous familiariser avec la documentation, et ces deux pages wiki https://github.com/ramda/ramda/wiki/What-Function-Should-I-Use%3F https://github.com/ ramda/ramda/wiki/Livre de recettes. Encore mieux si vous pouvez essayer et comprendre pourquoi les exemples fonctionnent! La série Pensée dans le blog de ramda est également très bien http: // randycoulman.com/blog/2016/05/24/thinking-in-ramda-getting-started/ Une des choses les plus importantes est aussi que certaines de ces fonctions font partie de ramda, mais dans l'ensemble les idées sont beaucoup plus grandes que ramda . Expérimentez avec d'autres bibliothèques fp, des tutoriels et même des langues! –