2015-11-02 28 views
13

Szukam obsługi funkcji, które zwracają obietnice z funkcjami Ramdy innymi niż pipeP. Próbuję porównać funkcje (z których jedna zwraca obietnicę) z równymi wartościami:Obsługa programowania asynchronicznego z Ramdą

getSectionFromDb :: obj -> promise 
getSectionFromData :: obj -> number 

R.equals(
    getSectionFromDb, 
    getSectionFromData 
) 

Są tu dwa czynniki. Pierwsze R.equals nie będzie oceniać funkcji, ale tym większy problem, że porównuję obietnicę z liczbą.

Czy istnieje funkcjonalny sposób robienia tego rodzaju rzeczy (wiem, że funkcje nie są referencyjne przezroczyste, ale musi istnieć sposób radzenia sobie z io)? Czy jest sposób na zrobienie tego w Ramdzie?

Dzięki.

+2

Brzmi tak, jakbyś chciał "podnieść" funkcję "równa się" - najpierw w monadzie obietnicy, a następnie w funkcji aplikacyjnej; niestety Ramda może podnosić tylko listy. – Bergi

+0

Więc chcesz funkcji "??? :: (obj -> Obietnica ) -> (obj -> liczba) -> (obj -> Obietnica ) '? – Bergi

+0

@Bergi: Dokumentacja Ramdy nie nadaje się do tego, by tuleć, ale 'lift' ** [działa na dowolnym' Applicative Funktorze'] (https://github.com/ramda/ramda/blob/master/test/liftN .js # L42-L45) **. –

Odpowiedz

3

Możesz użyć Promise.resolve, aby "zawinąć" wartość w obietnicę.

getSectionFromDataPromise :: obj -> promise 
getSectionFromDataPromise = R.pipe(getSectionFromData , (val) => Promise.resolve(val)) 

W ten sposób można promować (podnosić) dowolną funkcję, która zwraca normalną wartość do tej, która zwraca obietnicę.

Podnoszenie to podstawowa koncepcja w DF. Możesz zobaczyć Array.map jako funkcję, która podnosi funkcję, która przekształca wartość na funkcję, która przekształca tablicę wartości.

Możesz użyć funkcji Promise.all, aby napisać funkcję porównującą obietnice i (na przykład) zgłasza błąd, jeśli nie są one równe.

function promiseEquals (f1, f2) { 
    return Promise.all([f1(), f2()]).then(function(vals) { 
    if(!R.equals(vals[0], vals[1])) {throw "The values aren't equal"} 
    return vals[0] 
    }) 
} 

Wreszcie można połączyć dwa:

promiseEquals(getSectionFromDataPromise, getSectionFromDb) 
    .then(function(val){ 
    console.log(val) 
    }) 
    .catch(function(val){console.log("Error "+val)}) 
+0

Czy nie jest to (val) => Promise.resolve (val) tylko gadatliwy sposób wypowiedzenia Promise.resolve? – arcseldon

+0

idealnie tak, w JS nr. Funkcja rozstrzygania nie jest związana z obiektem obietnicy. –

+1

@arcseldon Możesz zrobić 'getSectionFromDataPromise = R.pipe (getSectionFromData, Promise.resolve.bind (Promise));' –

9

wiem, kwestia jest stary. Ale ramda ma kilka fajnych funkcji do komponowania funkcji zwracających Promise: pipeP i composeP.

wziąć także zajrzeć do regularnego compose (pipe) i jego realizacja Kleisli composeK (pipeK). Pozwalają one na pracę ze strukturami algebraicznymi, takimi jak Przyszłość lub Zadanie, które wyglądają tak samo jak Obietnica, ale są leniuchowane.