如何从 Promise<User> 获取用户名?

Posted

技术标签:

【中文标题】如何从 Promise<User> 获取用户名?【英文标题】:How to obtain username from Promise<User>? 【发布时间】:2020-11-22 22:57:52 【问题描述】:

我正在使用 Discord.js,但我不知道如何从 Promise 中获取价值。这是一些上下文:

///File: commands/mail.js///
module.exports = 

        name: 'mail',
        description: 'A system of collecting, sending, and receiving mail',
        async execute(client,message, args) 
                const fs = require('fs');
        ...
                ...
                        switch(args[0])
                        ...
                        case "check":
                            ...
                            var name;
                            var val;
/*  [object Promise]-->  */ var out = client.users.fetch(recipient.senders[i]);
                            client.users.fetch(recipient.senders[i]).then((name)=>
                                console.log("name.username(inside): "+name.username);
                                val = name.username;
                                return (name);
                            );
                            console.log("name(outside): ",name);
                            console.log("out: ",out);
                            console.log("out.username: ",out.username);
                            console.log("val: ",val);
                            
                            /* next line will get an error saying name.username is undefined */
                            //console.log("name.username(outside): "+name.username); 
                            ...

我得到了输出:

name(outside): undefined
out:  Promise 
  User 
    id: '1456051390970320640',
    bot: false,
    username: 'Sir_Ross',
    discriminator: '3871',
    avatar: 'a956037b05108e4971b93f3ffde97b6c',
    lastMessageID: '739552900342349856',
    lastMessageChannelID: '739150130339340342',
    flags: UserFlags  bitfield: 0 
  

val: undefined
out.username: undefined
name.username(inside): Sir_Ross

我的问题是我显然可以获取我的用户名并将其打印到控制台,但我无法将其从 Promise 中取出。如何从 Promise 中获取价值,以便我可以在其他地方使用它?

完整代码:

module.exports = 

    name: 'mail',
    description: 'A system of collecting, sending, and receiving mail',
    async execute(client,message, args) 
        const fs = require('fs');
        var path;
        if(!args.length)
            //No Arguments

            return 0;
        
        
        switch(args[0])
            case "send":
                // Send Mail
                if(args.length<3)
                    message.reply('Invalid Arguments: !mail send <recipient_id> <message>');
                else
                    letter = "";
                    spaces = 0;
                    for(i = 0; i<message.content.length;i++)
                        if(spaces<3)
                            if(message.content[i]===' ')
                                spaces++;
                            
                            continue;
                        else
                            letter+=message.content[i];
                        
                    
                    
                    const fs = require('fs');
                    path = 'mail/';
                    path+=args[1].substring(3,21);
                    sender = message.author.id;
                    path+='.json';
                    console.log(path);
                    if(!fs.existsSync(path))
                        user = 
                            user_id: args[1].substring(3,21),
                            //username: message.author.username,
                            mailbox: [letter],
                            senders: [sender],
                            //status:   0 ,
                            status: ['0'],
                        ;
                        data = JSON.stringify(user);
                        fs.writeFileSync(path,data);
                    else
                        var recipient;
                        fs.readFile(path,(err,data) =>
                            if(err) throw err;
                            recipient=JSON.parse(data);
                            //console.log(recipient);
                            recipient.mailbox.push(letter);
                            recipient.senders.push(message.author.id);
                            recipient.status.push('0');
                            console.log(recipient);

                            fs.writeFileSync(path,JSON.stringify(recipient));
                        );
                    
                
                break;
            case "check":
                // Check Inbox
                const fs = require('fs');
                path = 'mail/';
                path+=message.author.id;
                // sender = message.author.id;
                path+='.json';
                if(!fs.existsSync(path))
                    message.reply("Mailbox does not yet exist! You need to receive mail first!");
                    return;
                    //break;
                else
                    var recipient;
                    fs.readFile(path,(err,data) =>
                        if(err) throw err;
                        recipient=JSON.parse(data);
                        if(!recipient.senders.length)
                            message.reply("Mailbox is empty!");
                            return;
                            //break;
                        else
                        outText = "";
                        for(i = 0; i<recipient.senders.length;i++)
                            if(recipient.status[i]==='0')outText+="**";
                            outText+=i+1;
                            outText+=". ";
                            //console.log("Promise: ",client.users.fetch(recipient.senders[i]));
                            var name;
                            var val;
                            var out = client.users.fetch(recipient.senders[i]);
                            client.users.fetch(recipient.senders[i]).then((name)=>
                                console.log("name.username(inside): "+name.username);
                                val = name.username;
                                return (name);
                            );
                            console.log("name(outside): ",name);
                            console.log("out: ",out);
                            console.log("out.username: ",out.username);
                            console.log("val: ",val);
                            /*  name.username is undefined */
                            //console.log("name.username(outside): "+name.username); 
                            // esc = returnVal();
                            outText+=val;
                            if(recipient.status[i]==='0')outText+="**";
                            outText+='\n';
                        
                        message.reply(outText);
                        
                    );
                
                break;
            case "read":
                // Read Mail
                break;
            case "delete":
                // Delete Mail
                break;
            case "markRead":
                // Mark a Message as Read
                break;
            case "markUnread":
                // Mark a Message as Unread
                break;
            case "forward":
                // Forward a message
                break;
        
    ,
;

【问题讨论】:

只要await 它,因为你在async 函数中? @Bergi 问题是你需要在async 函数中创建一个await,它说我不再在async 函数中 那么请分享您的实际代码,因为从您发布的内容来看,您的问题发生在 async execute(client,message, args) 方法中。 啊,你在 fs.readFile 回调中。不要那样做 - promisify the readFile method 并写 const data = await readFileAsync(path); const recipient = JSON.parse(data); … 这样你的 fetch 调用仍然在 execute 内。 @Bergi 我搞定了,非常感谢! 【参考方案1】:

正如@Bergi 在他的评论中所说,我需要将我的代码从fs.readFile 回调中取出。 为此,我修改了我的代码:

var recipient;
fs.readFile(path,(err,data) =>
    if(err) throw err;
    recipient=JSON.parse(data);
    ...

进入

function readFileAsync(path)
    return new Promise(function(resolve, reject) 
        fs.readFile(path, function(err,data)
            if(err!==null)reject(err);
            else resolve(data);
        );
    );

const data = await readFileAsync(path); const recipient = JSON.parse(data);

他的链接很有用(特别是3. Node style callback ("nodeback")部分):How do I convert an existing callback API to promises?

【讨论】:

以上是关于如何从 Promise<User> 获取用户名?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 promise 中设置 react hook 的值?

如何在 promise 中设置 react hook 的值?

promise 使用场景

当我从等待移动到 Promise.all 时,TypeScript 函数返回类型错误

确保我在 laravel 5 中获得了正确的外键语法

使用 future<> 和 promise<> 进行消息传递?