首页 > 解决方案 > 异步代码乱序随机丢失变量减速

问题描述

我一直有这个代码错误,因为 createChannel 部分试图在定义“newChannelRole”之前运行我知道这是由于异步函数的某些性质,但我似乎无法找出确保事情发生的正确方法为了。特别是因为它发生在我的代码的哪些部分似乎是随机的

    async run(msg,args){
        //get our guilds Information
        let guildID = msg.guild.id;
        let locationDataKey = guildID+"_mapData";

        //Our Guild Settings
        let settingMapKey = guildID+"_setting";
        let settings = settingsMap.get(settingMapKey);

        //load up our location Data Array
        let locationDataArray = data.get(locationDataKey);

        //make the new channel
        let formatedNameDashes = args.name.replace(/ /g,"-");
        let formatedNameSpace  = args.name.replace(/-/g," ")

        //make a role for the channel
        let newChannelRole;
        msg.guild.createRole({
            name:formatedNameSpace
        }).then( x => {
            newChannelRole = x;
        });

        //Make the Channel and set the new permissions
        //Everyone has none, NPCs and the unique channel role can see it/type/read history
        msg.guild.createChannel(formatedNameDashes,{
            type:'text',
            permissionOverwrites:[
                {
                    id:msg.guild.defaultRole,
                    deny: ['VIEW_CHANNEL','SEND_MESSAGES','READ_MESSAGE_HISTORY']
                },
                {
                    id:settings.npcRoleID,
                    allow:['VIEW_CHANNEL','SEND_MESSAGES','READ_MESSAGE_HISTORY']
                },
                {
                    id:newChannelRole.id,
                    allow:['VIEW_CHANNEL','SEND_MESSAGES','READ_MESSAGE_HISTORY']

                }
            ]
        }).then( channel => {
            //move it into the category
            let rpCategory = msg.guild.channels.get(settings.rpCategoryID)
            channel.setParent(rpCategory);

            //push the information into the locationDataArray
            mapDataArray.push({
                name:formatedNameSpace,
                channelName:channel.name,
                connections:[],
                channelID:channel.id
            });

            //save the locationDataArray
            data.set(locationDataKey,locationDataKey);     
        });   
    }

标签: javascriptnode.jsdiscord.js

解决方案


问题是您调用后的代码then不会等待then连接到的承诺解决。要让它等待,您必须将其全部放在该行then之后的处理程序中newChannelRole = x;

但是由于您使用的是async函数,所以不要使用.then,使用await. 见***评论:

async run(msg,args){
    //get our guilds Information
    let guildID = msg.guild.id;
    let locationDataKey = guildID+"_mapData";

    //Our Guild Settings
    let settingMapKey = guildID+"_setting";
    let settings = settingsMap.get(settingMapKey);

    //load up our location Data Array
    let locationDataArray = data.get(locationDataKey);

    //make the new channel
    let formatedNameDashes = args.name.replace(/ /g,"-");
    let formatedNameSpace  = args.name.replace(/-/g," ")

    //make a role for the channel
    let newChannelRole = await msg.guild.createRole({                        // ***
        name:formatedNameSpace
    });

    //Make the Channel and set the new permissions
    //Everyone has none, NPCs and the unique channel role can see it/type/read history
    const channel = await msg.guild.createChannel(formatedNameDashes,{       // ***
        type:'text',
        permissionOverwrites:[
            {
                id:msg.guild.defaultRole,
                deny: ['VIEW_CHANNEL','SEND_MESSAGES','READ_MESSAGE_HISTORY']
            },
            {
                id:settings.npcRoleID,
                allow:['VIEW_CHANNEL','SEND_MESSAGES','READ_MESSAGE_HISTORY']
            },
            {
                id:newChannelRole.id,
                allow:['VIEW_CHANNEL','SEND_MESSAGES','READ_MESSAGE_HISTORY']

            }
        ]
    });

    //move it into the category
    let rpCategory = msg.guild.channels.get(settings.rpCategoryID)
    channel.setParent(rpCategory);

    //push the information into the locationDataArray
    mapDataArray.push({
        name:formatedNameSpace,
        channelName:channel.name,
        connections:[],
        channelID:channel.id
    });

    //save the locationDataArray
    data.set(locationDataKey,locationDataKey);     
}

请注意,任何调用都run需要处理返回承诺的事实run(因为所有 async函数都返回承诺)。特别重要的是,无论调用它处理承诺拒绝(或将承诺传递给将)。


推荐阅读