Returning promise value from function [duplicate]

对着背影说爱祢 提交于 2021-02-08 05:49:26

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!