问题
I am trying to make this recursive function return a promise value, I don't know how to go about doing it, I have tried writing it in different ways but they all ended up with search
being undefined
public search(message: Message) {
let search: string;
const filter = (msg: Message) => msg.author.id === message.author.id;
message.channel.send('Enter search term').then(msg => {
message.channel.awaitMessages(filter, { max: 1 })
.then(collected => {
if (collected.first()!.content === 'Test') this.search(message);
msg.delete()
collected.first()!.delete()
search = collected.first()!.content
})
})
})
return search; // Variable 'search' is used before being assigned.ts(2454)
}
回答1:
Have you considered using an async function? That alone would make your code easier to debug and understand.
public async search(message: Message): Promise<any> {
const filter = (msg: Message) => msg.author.id === message.author.id;
const msg = await message.channel.send('Enter search term');
const collected = await message.channel.awaitMessages(filter, { max: 1 });
if (collected.first()!.content === 'Test') return this.search(message);
msg.delete();
collected.first()!.delete();
const search = collected.first()!.content;
return search;
}
Here, search
is defined as a const and immediately returned, and that's fine to the compiler.
I didn't use a variable to save the return value of the nested this.search
call, but you may have to if you decide to execute more code after calculating the actual result.
回答2:
search
will always be undefined because the function returns before any asynchronous action returns. You need to return the first Promise and then perform any further asynchronous actions within the .then
callbacks:
public search(message: Message) {
const filter = (msg: Message) => msg.author.id === message.author.id;
// immediately return the first promise
return message.channel.send('Enter search term').then(msg => {
// then when we get a message out of the first promise return the second one
return message.channel.awaitMessages(filter, { max: 1 }).then(collected => {
// then return the desired value at the end
if (collected.first()!.content === 'Test') this.search(message);
msg.delete();
collected.first()!.delete();
return collected.first()!.content;
});
});
}
Ideally, we want to avoid nesting promises to get rid of the deep callback hell that they were invented to destroy:
public search(message: Message) {
const filter = (msg: Message) => msg.author.id === message.author.id;
return message.channel.send('Enter search term')
.then(msg => Promise.all([
msg,
message.channel.awaitMessages(filter, { max: 1 })
]))
.then(([msg, collected]) => {
if (collected.first()!.content === 'Test') this.search(message);
msg.delete();
collected.first()!.delete();
return collected.first()!.content;
});
}
By using Promise.all
we can avoid having to nest promises and still have access to previously resolved values.
来源:https://stackoverflow.com/questions/61719050/returning-promise-value-from-function