Simple library for interop between Aff and JavaScript promises.
No typeclass instances etc are provided to use Promises directly - the intention is that your PureScript code uses Aff internally, and is only wrapped as a Promise to present an API for consumption in JavaScript code (and vice versa).
The origin of this library was to solve the following problem: I want to write asynchronous code in Aff
, but I need
to expose this as an API to JavaScript in the form of a Promise
.
Therefore the majority of code can be written to return an Aff
, in this example using readTextFile
from
purescript-node-fs-aff:
getLinesAff :: Aff (Array String)
getLinesAff = do
text <- readTextFile Encoding.UTF8 "data.txt"
pure $ split (Pattern "\n") text
and this can be exposed as a function returning a promise:
import Control.Promise as Promise
getLines :: Effect (Promise (Array String))
getLines = Promise.fromAff getLinesAff
This function returns an Effect
beause a promise is "already running". A JavaScript function consuming this API
would just call getLines().then(...)
.
The reverse problem occurs when wrapping a JS library that uses promises for asynchronous behaviour (Aff
comes
with a perfectly good function to deal with consuming libraries that use callbacks).
Consider the case of consuming the fetch
API.
exports.fetchImpl = function (url) {
return function() {
return fetch(url);
};
}
foreign import data Response :: Type
foreign import fetchImpl :: String -> Effect (Promise Response)
Notice that the fetch(url)
call is wrapped in a thunk and imported as an Effect
, because otherwise the fetch
operation would be initiated as a side-effect of a pure function - while fetch
returns a promise, at the point
the function returns the network request has already been initated.
The response can then be converted to an Aff
and consumed easily:
import Control.Promise as Promise
fetch :: String -> Aff String
fetch url = liftEffect (fetchImpl url) >>= Promise.toAff
API documentation is available on Pursuit.