Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 尽管在异步函数中返回了值,Promise始终解析为null_Typescript_Promise - Fatal编程技术网

Typescript 尽管在异步函数中返回了值,Promise始终解析为null

Typescript 尽管在异步函数中返回了值,Promise始终解析为null,typescript,promise,Typescript,Promise,我的async函数有问题 在内部promisethen回调中,值设置正确,但在返回此变量并解析promise之后,调用方始终会得到一个空值 注意:这是针对discord机器人的:我尝试使用用户ID获取用户的显示名称 以下是async函数: export async function getUserInfo(userNameLooking: string, guild: Guild): Promise<UserSettings | null> { console.log(&quo

我的
async
函数有问题

在内部promise
then
回调中,值设置正确,但在返回此变量并解析promise之后,调用方始终会得到一个空值

注意:这是针对discord机器人的:我尝试使用用户ID获取用户的显示名称

以下是
async
函数:

export async function getUserInfo(userNameLooking: string, guild: Guild): Promise<UserSettings | null> {

  console.log("Looking for user", userNameLooking);

  userList.forEach(user => {

    console.log("Analyzing user ID", user);

    let thanos = guild.client.users.fetch(user);
    thanos.then(function (result1) {

      console.log("... This ID user name is", result1.username);

      if (result1.username.toLowerCase() == userNameLooking.toLowerCase()) {
        console.log("... Match !");
        console.log(cacheUser[user] );

        return  cacheUser[user] ;
      }
      else {
        console.log("... Not match ...");
      }
    }, function (){console.log("ERROR : Can't find name of ID", user)});
  })

  return null;
}

问题出在哪里?

您的函数
getUserInfo
只有一个
return
语句,它返回
null
,因此它无法返回其他数据,以供承诺解决

问题是您的数据在
forEach
回调函数中返回。但这个返回值将被遗忘。在
forEach
回调中返回数据是无用的。它没有任何用途

您必须返回所有promise对象,您应该使用
.map
,而不是
.forEach
。然后使用
Promise.all
等待所有这些承诺得到解决。然后使用
.find
在未定义的值中查找第一个解析值。这是您希望用
getUserInfo
承诺解析的值:因此返回该值

以下是它的工作原理:

export async function getUserInfo(userNameLooking: string, guild: Guild): Promise<UserSettings | null> {
    let results = await Promise.all(userList.map(user => {
//                      ^^^^^^^^^^^          ^^^ 
        let thanos = guild.client.users.fetch(user);
        return thanos.then(function (result1) {
//      ^^^^^^ 
            if (result1.username.toLowerCase() == userNameLooking.toLowerCase()) {
                return  cacheUser[user];
            }
        });
    });
    // Find the first non-undefined result, 
    // ... assuming that `catchUser[user]` is a truthy value.
    return results.find(Boolean);
}

Trincot的回答将针对所有用户运行查询,但即使在找到第一个结果后,它也会等待所有查询完成,然后再解析结果。这就是使用允诺的效果。所有这些都是他在回答中使用允诺的方式

我们真正想要的是一个类似于
Array.prototype.find的函数,但它接受一系列承诺。它应该在每一个上运行
测试
功能,但是
只要第一个
通过测试,就可以解决问题。如果没有通过测试的承诺值,请解决
undefined
-

异步函数查找(承诺、测试){ 返回新承诺((解决、拒绝)=>{ for(承诺的常数) p、 然后(值=>测试(值)和解析(值),拒绝) Promise.all(promises).then(=>resolve(未定义)) }) }
find
作为一个通用函数编写是很有用的,因为它允许
getUserInfo
只关注它的特殊关注点。它还使我们能够重用
查找程序中需要的其他位置,而无需编写复杂的代码-

函数getUserInfo(查询,公会){
返回查找
(userList.map(用户=>guild.client.users.fetch(用户))
,结果=>
result.username.toLowerCase()==query.toLowerCase()
)
。然后(user=>user&&cacheUser[user])
}
让我们使用下面的演示程序来看看
find
-

异步函数查找(承诺、测试){ 返回新承诺((解决、拒绝)=>{ for(承诺的常数) p、 然后(值=>测试(值)和解析(值),拒绝) Promise.all(promises).then(=>resolve(未定义)) }) } const sleep=ms=> 新承诺(r=>setTimeout(r,ms)) 异步函数获取(查询){ 等待睡眠(Math.random()*3000) 返回查询 } 常量查询= [“爱丽丝”、“鲍勃”、“卡拉”、“迪娜”] 查找(querys.map(fetch),result=>result.length>4) .然后(console.log,console.error)/“卡拉”或“爱丽丝” 查找(querys.map(fetch),result=>result.length>5)
.then(console.log,console.error)//undefined
您的函数执行一个
forEach
,然后执行
返回null。你还指望什么?这是它拥有的单个
return
语句。但是在foreach中有一个return。。。否?是的,但这是回调函数的(无用)返回值,而不是外部函数的返回值。我理解,我将学习.map函数!谢谢!这个答案解释得很好,但在找到第一个匹配项时不会出现短路。请参阅我的答案,了解另一种方法:染料,@ThankYou,我也想到了捷径——这取决于第三方API,这可能会带来一些时间收益。我在我的答案中添加了一个替代的捷径解决方案,它不需要
新承诺
。对
承诺进行了很好的调整。任何
,但请注意,此解决方案都会吞下
获取
过程中可能出现的其他自然错误。
export async function getUserInfo(userNameLooking: string, guild: Guild): Promise<UserSettings | null> {
    let results = await Promise.all(userList.map(user => {
//                      ^^^^^^^^^^^          ^^^ 
        let thanos = guild.client.users.fetch(user);
        return thanos.then(function (result1) {
//      ^^^^^^ 
            if (result1.username.toLowerCase() == userNameLooking.toLowerCase()) {
                return  cacheUser[user];
            }
        });
    });
    // Find the first non-undefined result, 
    // ... assuming that `catchUser[user]` is a truthy value.
    return results.find(Boolean);
}
// In this version the function does not really need to be declared `async`:
export function getUserInfo(userNameLooking: string, guild: Guild): Promise<UserSettings | null> {
    return Promise.any(userList.map(user => {
//                 ^^^ 
        let thanos = guild.client.users.fetch(user);
        return thanos.then(function (result1) {
            if (result1.username.toLowerCase() == userNameLooking.toLowerCase()) {
                return  cacheUser[user]; // <-- will resolve the `.any` promise
            }
            // Throwing will avoid resolving the `.any` promise
            //  ... unless this is the last one, and there was no match found
            throw new Error("no match"); 
        });
    }).catch(() => null); // resolve to null when nothing matches
}