我有一个异步函数,该函数调用数据库并返回一个字符串(承诺)。但是,当我调用此函数时,我无法定义
异步功能:
printf -v "$2" '%s' "$answer"
然后我从这里调用此函数,但是在控制台中未定义它:
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);
})
}
答案 0 :(得分:2)
它是未定义的,因为您实际上并没有从initialiseChannelDatabase
函数返回任何内容。
由于您使用的是异步功能,因此在使用异步功能时也应使用“ await”,这样可以更轻松地处理这种情况,而无需其他闭包和回调:
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;
}
}
有关异步的其他信息/等待this link
编辑:删除了内部try-catch,因为在失败的情况下,它将触发第一个捕获,并且还是可以的。
答案 1 :(得分:1)
问题在于您永远不会从initializeChannelDatabase
返回。其中唯一的return语句位于then
和catch
回调中。因此它们是从回调函数返回的,而不是从initializeChannelDatabase
返回的。
在您的诺言return
/ then
链之前添加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);
})
}
但是,由于您的函数已经使用了async
关键字,因此您最好也使用await
功能而不是构建承诺链。
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
。这将确保返回的诺言被拒绝。使呼叫者进入备用catch
路径。如果打算将成功和失败合并在一起,则可以保留原样。
答案 2 :(得分:-2)
您返回Promise.resolve(SUCCESS)
,但是变量SUCCESS
在代码中未定义。
您的意图可能是像MDN文档中那样返回字符串'SUCCESS'
:
Promise.resolve('Success').then(function(value) {
console.log(value); // "Success"
}, function(value) {
// not called
});