从函数返回承诺值[重复]

Posted

技术标签:

【中文标题】从函数返回承诺值[重复]【英文标题】:Returning promise value from function [duplicate] 【发布时间】:2020-08-26 08:46:03 【问题描述】:

我正在尝试让这个递归函数返回一个承诺值,我不知道该怎么做,我尝试过以不同的方式编写它,但它们都以 searchundefined

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)
  

【问题讨论】:

如果你想返回一个承诺,你为什么要尝试return search 【参考方案1】:

您是否考虑过使用异步函数?仅此一项就可以使您的代码更易于调试和理解。

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;

这里,search 被定义为 const 并立即返回,这对编译器来说很好。 我没有使用变量来保存嵌套的this.search 调用的返回值,但是如果您在计算实际结果后决定执行更多代码,则可能必须这样做。

【讨论】:

【参考方案2】:

search 将始终未定义,因为函数在任何异步操作返回之前返回。您需要返回第一个 Promise,然后在 .then 回调中执行任何进一步的异步操作:

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;
    );
  );

理想情况下,我们希望避免嵌套 promise 以摆脱它们被发明用来破坏的深层回调地狱:

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;
    );

通过使用Promise.all,我们可以避免嵌套promise,并且仍然可以访问之前解析的值。

【讨论】:

我现在面临的问题是,当我满足它无论如何都会返回并导致其余代码运行使递归函数无用的条件时

以上是关于从函数返回承诺值[重复]的主要内容,如果未能解决你的问题,请参考以下文章

承诺后的返回值[重复]

从 axios.get 返回的承诺 [重复]

使用 .map 分配返回的承诺的值 [重复]

如何按顺序执行承诺并返回所有结果[重复]

将变量保存在具有承诺的函数中的Javascript问题[重复]

如何将我的代码从回调函数更改为承诺 [重复]