Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/476.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
Javascript 异步函数返回未定义的类型_Javascript_Asynchronous_Discord.js - Fatal编程技术网

Javascript 异步函数返回未定义的类型

Javascript 异步函数返回未定义的类型,javascript,asynchronous,discord.js,Javascript,Asynchronous,Discord.js,我有一个异步函数,它调用数据库并返回字符串(promise)。然而,当我调用这个函数时,我得到了未定义的结果 异步函数: const SUCCESS = 'Channel storage initialized succesfully'; const FAIL = 'There has been a problem initializng this channel'; const EXISTS = 'Channel already initialized' initializeChannelD

我有一个异步函数,它调用数据库并返回字符串(promise)。然而,当我调用这个函数时,我得到了未定义的结果

异步函数:

const SUCCESS = 'Channel storage initialized succesfully';
const FAIL = 'There has been a problem initializng this channel';
const EXISTS = 'Channel already initialized'

initializeChannelDatabase = async channelNum =>{
    const db = admin.firestore();
    db.collection('channels').doc(channelNum).get().then(res=>{
        if(!res.exists){
            db.collection('channels').doc(channelNum).set({isPremium: false}).then(res=>{
                return Promise.resolve(SUCCESS);
            }).catch(err=>{
                return Promise.resolve(FAIL);
            })
        }else{
            return Promise.resolve(EXISTS);
        }
    }).catch(err=>{
        return Promise.resolve(FAIL);
    })
}
然后我从这里调用此函数,但在控制台中未定义:

client.on('message', async msg => {
    if(msg.content==='\'init'){
        initializeChannelDatabase(msg.channel.id).then(result=>{
            console.log(result);
            if(result===SUCCESS){
            ...

您返回
Promise.resolve(SUCCESS)
但变量
SUCCESS
在代码中未定义。 您的意图可能是像MDN文档中那样返回字符串
'SUCCESS'

Promise.resolve('Success')。然后(函数(值){
console.log(值);/“成功”
},函数(值){
//不打电话
});

它是未定义的,因为您实际上没有从
initialiseChannelDatabase
函数返回任何内容

由于您使用的是async,因此在使用异步函数时还应使用“wait”,这样在不使用额外闭包和回调的情况下,处理这种情况会更容易:

initializeChannelDatabase = async channelNum => {

    const db = admin.firestore();

    try {

        let channelDoc = await db.collection('channels').doc(channelNum).get();
    
        if (!channelDoc.exists) {

            await db.collection('channels').doc(channelNum).set({ isPremium: false });
    
            return SUCCESS;

        } else {
            return EXISTS;
        }

    } catch (err) {
        return FAIL;
    }
}
关于异步/等待的其他信息


编辑:删除了内部try-catch,因为如果失败,它将触发第一个catch,并且无论如何都会正常。

问题是您永远不会从
initializeChannelDatabase返回。其中唯一的返回语句放在
然后
catch
回调中。因此,它们从回调函数返回,而不是从
initializeChannelDatabase
返回

在承诺前添加
return
语句
然后
/
catch
链应该可以解决问题并返回承诺链生成的最终承诺

initializeChannelDatabase = async channelNum => {
    const db = admin.firestore();
    return db.collection('channels').doc(channelNum).get().then(res=>{
    // ^ return the promise chain
        if(!res.exists){
            return db.collection('channels').doc(channelNum).set({isPremium: false}).then(res=>{
            // ^ return the nested promise chain
                return Promise.resolve(SUCCESS);
            }).catch(err=>{
                return Promise.resolve(FAIL);
            })
        }else{
            return Promise.resolve(EXISTS);
        }
    }).catch(err=>{
        return Promise.resolve(FAIL);
    })
}
initializeChannelDatabase = async channelNum => {
    const db = admin.firestore();
    
    try {
        const channel = await db.collection('channels').doc(channelNum).get();
        if (channel.exists) return EXISTS;
        await db.collection('channels').doc(channelNum).set({isPremium: false});
        return SUCCESS;
    } catch (error) {
        return FAIL;
    }
}
但是,由于您的函数已经使用了
async
关键字,因此您最好使用
wait
功能,而不是构建承诺链

initializeChannelDatabase = async channelNum => {
    const db = admin.firestore();
    return db.collection('channels').doc(channelNum).get().then(res=>{
    // ^ return the promise chain
        if(!res.exists){
            return db.collection('channels').doc(channelNum).set({isPremium: false}).then(res=>{
            // ^ return the nested promise chain
                return Promise.resolve(SUCCESS);
            }).catch(err=>{
                return Promise.resolve(FAIL);
            })
        }else{
            return Promise.resolve(EXISTS);
        }
    }).catch(err=>{
        return Promise.resolve(FAIL);
    })
}
initializeChannelDatabase = async channelNum => {
    const db = admin.firestore();
    
    try {
        const channel = await db.collection('channels').doc(channelNum).get();
        if (channel.exists) return EXISTS;
        await db.collection('channels').doc(channelNum).set({isPremium: false});
        return SUCCESS;
    } catch (error) {
        return FAIL;
    }
}

我还强烈建议使用
thow FAIL/EXISTS
而不是
return FAIL/EXISTS
。这将确保退回的承诺被拒绝。将调用者置于备用
捕获路径中。如果目的是将成功和失败合并在一起,则可以保持原样。

它们在代码中以前定义为字符串。很抱歉没有包括我认为没有必要的内容。我已经编辑了代码,在顶部包含了字符串。我想退回其中一个。如果.then()执行成功,如果.catch()执行失败,请注意当
channel.EXISTS
为true时,用户返回的内容存在。答案很好:)@Drago96很好,在将if语句转换为保护子句时忘记了反转if语句。我已经更新了代码。