Reputation: 780
I'm trying to curry a function but when the first one is async it throws the error function1(...) is not a function
, however if I pass the async function as the last one it works fine.
Can anyone tell me why this is happening? and how to properly make a curry function that starts with a async function?
Thanks to anyone who take the time.
//This one is throwing the error: function1(...) is not a function
async function function1(path) {
const fetchedElement = await fetchElement(path);
//(...)
return (msg) => {
console.log(msg);
};
}
function1('somepath.html')('my message');
//This one works fine, properly returning other function
function function2(path) {
return async (msg) => {
const fetchedElement = await fetchElement(path);
//(...)
console.log(msg);
};
}
function2('somepath.html')('my message');
Upvotes: 2
Views: 685
Reputation: 62686
It depends on when the async work needs to get done. If you want the currying process to do the async work, then you can't invoke the currying function synchronously:
curryingFunction(paramA)(paramB)
^ assumes curryingFunction is synchronous
Instead, use two statements by the caller, one to await the currying, the other to invoke...
const fetch = path => new Promise(resolve => setTimeout(() => {
console.log('fetched ' + path)
resolve()
}, 1000));
async function curryingFunction(path) {
const fetchedElement = await fetch(path);
return message => {
console.log(message);
}
}
async function someCaller() {
// await to get a curried function, then invoke it
let curried = await curryingFunction('some_path');
curried('some message');
}
someCaller()
On the other hand, you might not need to do the async work in order to get the curried function. You probably don't. In that case, you can make the currying function synchronous, but have it return an async function that does the async work.
As a result, you'll get to use the fn()()
syntax that you're probably used to using...
const fetch = path => new Promise(resolve => setTimeout(() => {
console.log('fetched ' + path)
resolve()
}, 1000));
function curryingFunction(path) {
return async (message) => {
const fetchedElement = await fetch(path);
console.log(message);
}
}
async function someCaller() {
// here we can use the fn()() syntax that we're accustomed to
await curryingFunction('some path')('some message')
}
someCaller()
Upvotes: 1
Reputation: 17604
As the first function is async
You need to await
it first, then call the second parameter.
//This one is throwing the error: function1(...) is not a function
async function function1(path) {
const fetchedElement = await Promise.resolve(1);
//(...)
return (msg) => {
console.log(msg);
};
}
(async () => {
try {
(await function1('somepath.html'))('my message');
} catch(e) {
console.log(e)
}
})()
Upvotes: 1