Node.js中如何将getDatafromCosmosDB的回调结果赋值给main函数变量
问题本质
你的代码无法拿到返回值的核心原因是异步操作的执行顺序问题:
getDatafromCosmosDB内部的CosmosDB查询是异步操作,不会等待结果返回就会结束函数执行,直接同步取值自然拿不到结果- 你给
getDatafromCosmosDB标注的async关键字当前没有实际作用,函数既没有返回Promise也没有使用await调用其他异步操作
方案1:保持回调风格实现
如果不想改动原有函数的回调设计,只需要把使用返回值的逻辑全部放到回调函数内部即可,只有回调被触发时才代表异步查询已经完成,结果可用:
async function main(params, callback) { const logger = Core.Logger('main2', { level: params.LOG_LEVEL || 'info' }) try { logger.info('main action') getDatafromCosmosDB(function(response){ const respdata = response console.debug(respdata) // 所有需要使用respdata的逻辑都需要写在这个回调内部 }); } catch (e) { console.debug(e) } } exports.main = main async function getDatafromCosmosDB(callback){ var query = new azure.TableQuery() .top(5) tableService.queryEntities('myCosmosTable', query, null, function (error, result, response) { if (!error) { console.log('success') return callback(result.entries) } // 建议补充错误场景的回调处理,避免错误丢失 callback(null, error) }); }
这种方案的问题是如果后续嵌套的异步逻辑变多,会出现回调地狱问题,可维护性差,更推荐使用Promise+await的方案。
方案2:封装为Promise配合async/await实现(推荐)
把回调风格的异步操作封装为Promise,就可以用await关键字直接以同步写法拿到异步返回结果,代码结构更清晰:
第一步:修改getDatafromCosmosDB返回Promise
// 移除callback参数,返回Promise对象 async function getDatafromCosmosDB(){ return new Promise((resolve, reject) => { var query = new azure.TableQuery() .top(5) tableService.queryEntities('myCosmosTable', query, null, function (error, result, response) { if (!error) { console.log('success') // 成功时返回查询结果 resolve(result.entries) } else { // 失败时抛出错误 reject(error) } }); }) }
第二步:修改main函数用await获取返回值
async function main(params, callback) { const logger = Core.Logger('main2', { level: params.LOG_LEVEL || 'info' }) try { logger.info('main action') // 添加await等待异步操作完成,直接拿到返回值赋值 const respdata = await getDatafromCosmosDB() console.debug(respdata) // 后续需要使用respdata的逻辑可以直接像同步代码一样写在这里 } catch (e) { // 数据库查询的错误会直接被这里的catch捕获 console.debug(e) } } exports.main = main
注意:await关键字只能在标记了async的函数内部使用,你现有的main函数已经加了async标记,不需要额外修改。
内容的提问来源于stack exchange,提问作者Scorpyon
相关产品推荐
相关产品推荐

