node.js - Argument av typen '() => Promise' kan inte tilldelas parametern av typen 'Promise'. ts(2345)
Jag definierar en funktion som kräver en asynkron funktion som parameter:
async function handle(def: Promise<string>) {
// ...
const data = await def;
console.log(`data equals: ${data}`)
}
Jag kan framgångsrikt utföra detta genom att skicka ett löfte.
handle(new Promise(async (res, rej) => {
const data = await Promise.resolve("some data")
if (data == "invalid")
return rej("data is invalid")
res(data)
}))
Jag behöver att inre funktionen är asynkron, eftersom jag behöver utföra await inuti. Däremot ogillar jag async i löftet och har läst online att det anses vara ett antipattern.
Jag tyckte att det var en bättre idé att göra sig av med löftet och använda en grundläggande asynkron funktion:
handle(async () => {
const data = await Promise.resolve("some data")
if (data == "invalid")
throw "data is invalid"
return data
})
Men TS-kompilatorn ger felet:
Argument of type '() => Promise<string>' is not assignable to parameter of type 'Promise<string>'. ts(2345)
Jag trodde att Promises och async-funktioner är något utbytbara. Jag läste att async-funktioner alltid returnerar ett promise. Tydligen tolkar jag detta inte korrekt, men jag är osäker på vad felet försöker säga mig.
Jag hoppas att problemet jag skisserar är tydligt. Det skulle uppskattas mycket om någon kunde klargöra felet eller ge förslag på hur man kan implementera detta på önskat sätt. Stort tack!
Svar #1
din funktionssignatur verkar vara felaktig. du definierar parametern som en Promise<string>, medan du egentligen vill att det ska vara () => Promise<string>.
async function handle(def: () => Promise<string>) {
// ...
const data = await def();
console.log(`data equals: ${data}`)
}
Svar #2
I allmänhet är tiden att använda Promise-konstruktören i en situation som denna precis när du anropar en callback-baserad funktion som du vill göra till ett löfte. Men här verkar det inte finnas något att göra till ett löfte, så Promise-konstruktören hjälper egentligen inte.
Om
Jag behöver att inre funktionen är asynkron, eftersom jag behöver använda await inuti.
Du kan ha en omedelbart anropad asynkron IIFE - ja, att använda en asynkron callback för Promise-konstruktören skulle inte vara säkert, eftersom det inte skulle hantera fel.
handle((async () => {
const data = await Promise.resolve("some data")
if (data == "invalid")
throw "data is invalid";
return data
})())
Det andra alternativet är att använda .then - .then är utbytbar med await i många situationer:
handle(
Promise.resolve("some data")
.then((data) => {
if (data == "invalid")
throw "data is invalid";
return data;
})
);
