I want to transform an imperative Promise
to a functional Task
in a principled fashion:
const record = (type, o) => (o[type.name || type] = type.name || type, o); const thisify = f => f({}); const taskFromPromise = p => Task((res, rej) => p.then(res).catch(x => rej(`Error: ${x}`))); const Task = task => record( Task, thisify(o => { o.task = (res, rej) => task(x => { o.task = k => k(x); return res(x); }, rej); return o; })); const tx = taskFromPromise(Promise.resolve(123)), ty = taskFromPromise(Promise.reject("reason").catch(x => x)); // ^^^^^ necessary to avoid uncaught error tx.task(console.log); // 123 ty.task(console.log); // "reason" but should be "Error: reason"
The resolution case works but the rejection doesn't, because Promise
s are eagerly triggered. If I dropped the catch
handler I would have to put the entire computation into a try
/ catch
statement. Is there a more viable alternative?
You don't need .catch(x => x)
, which turns your rejected promise into an resolved one. You shouldn't get an "uncaught error" since you have a catch
inside your taskFromPromise
function. Removing the .catch(x => x)
does work and lands you in .catch(x => rej(`Error: ${x}`))
instead.
However removing .catch(x => x)
does throw "TypeError: rej is not a function". From your code sample it it seems like your .task(...)
(in tx.task(...)
and ty.task(...)
) expects two functions. The first one is called if the promise resolves, the second one if the promise is rejected. Providing both functions leaves me with a working code snippet.
const record = (type, o) => (o[type.name || type] = type.name || type, o); const thisify = f => f({}); const taskFromPromise = p => Task((res, rej) => p.then(res).catch(x => rej(`Error: ${x}`))); const Task = task => record( Task, thisify(o => { o.task = (res, rej) => // expects two functions task(x => { o.task = k => k(x); return res(x); }, rej); return o; })); const tx = taskFromPromise(Promise.resolve(123)), ty = taskFromPromise(Promise.reject("reason")); // removed.catch(x => x) tx.task(console.log, console.log); // provide two functions ty.task(console.log, console.log); // ^ ^ // if resolved if rejected
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.