函数返回不工作

我在节点工作,并尝试从我的数据库加载下一个序列。 我能够访问数据库,加载并返回我的函数内的序列,但我无法访问它的function之外。

function getRunId() { counters.findOne({_id: 'Run_ID'}, function(err, resp) { if(err) { console.log(err); } console.log('Seq: ' + resp.sequence); // Console Output = Seq: 1234 return resp.sequence; }); }; var currentRunId = getRunId(); console.log('Run_ID: ' + currentRunId); // Console Output = CRID: undefined 

我已经检查了几个关于使用callback,asynchronous(节点模块),如何正确地返回函数中的值堆栈溢出问题的页面,但没有让我更接近访问currentRunIdfunction之外。

在我的函数内使用Mongo查询,这个问题进一步复杂化了吗?

对于任何人稍后磕磕碰碰, 开始阅读这个答案 。

我已经处理了几次,所以我明白了这个沮丧。 您正在尝试通过这样做混合同步和asynchronous代码:

 var currentRunId = getRunId(); console.log('Run_ID: ' + currentRunId); 

问题在于,在通过将getRunID()分配给当前RunID来调用getRunID()之后立即调用console.log('Run_ID:'+ currentRunId),并在console.log('Run_ID:'+ currentRunId)之后parsinggetRunID currentRunIdvariables是未定义的。

但是,你有一些select来处理这个问题。 选项一是返回一个callback,并loggingcallback的结果。 选项2是使用ES6的承诺。 要使用选项2,需要节点版本7,并且需要在代码中使用“严格使用”。

下面是围绕一个函数存根构build的3个示例,它欺骗了findOne()的结果。 getRunIdA()是你的函数,getRunIdB和getRunIdC是解决当前问题的两个例子。

 'use strict' // A function stub which represents a simplified version of findOne. // Accepts callback and returns a callback with the results of data function findOne (callback) { var data = { sequence: 6 } return callback(null, data) } // This is a simplified version of your function, which reproduces the undefined result function getRunIdA () { findOne(function (err, resp) { if (err) { console.log(err) } console.log('Seq: ' + resp.sequence) return resp.sequence }) } // This is your function with a callback function getRunIdB (callback) { findOne(function (err, resp) { if (err) { console.log(err) } console.log('Seq: ' + resp.sequence) return callback(resp.sequence) }) } // This is your function with a promise var getRunIdC = new Promise(function (resolve, reject) { resolve(findOne(function (err, resp) { if (err) { console.log(err) } return resp.sequence })) }) // Invoke your funciton; get undefined var currentRunID = getRunIdA() console.log('Run_ID: ' + currentRunID) // Run_ID: undefined // Invoke getRunIdB using callback, get 6 getRunIdB(function (id) { console.log('Run_ID: ' + id) // Run_ID: 6 }) // Invoke getRunIdC with a promise; get 6 getRunIdC.then(function (currentRunID) { console.log('Run_ID: ' + currentRunID) // Run_ID: 6 }) /* results for all 3: Seq: 6 Run_ID: undefined Seq: 6 Run_ID: 6 Run_ID: 6 */ 

通过保存到您的机器并运行:

节点test.js

在我的函数内使用Mongo查询,这个问题进一步复杂化了吗?

不,你只需要将你的查询的结果传递给一个承诺或callback,以便你可以在其他地方使用结果。

我希望这有帮助!

编辑:OP在评论中添加了以下代码,我将尝试分解和解决。

不幸的是,使用getRunIdB结果callback没有定义和使用getRunIdC结果currentRunId没有定义

 var currentRunID = ''; var getRunId = new Promise(function (resolve, reject) { resolve(counters.findOne({_id: 'Run_ID'}, function (err, resp) { if (err) { console.log(err) } return resp.sequence; })) }); getRunId.then(function (res) { console.log('Run_ID: ' + res.sequence) // Run_ID: 1234 currentRunID = res.sequence; }) console.log(currentRunID); // currentRunID is not defined 

查看关于JS并发模型的更多细节, 我给了类似问题的答案 。 简而言之,getRunID()函数正在执行asynchronous代码。 这意味着getRunID()不会被插入到消息队列中,这将决定JavaScript执行的顺序,直到callback完成。 因此,当您在.then()函数之外loggingcurrentRunID时,结果未定义,因为currentRunID未定义。

我认为最终OP所要做的就是导出函数的结果,以便可以用这些结果来完成某些事情,这需要在如下的callback中完成:

 getRunId.then(function (res) { // Do stuff with the run ID here. }) 

您只返回一个callback函数,但不是在实际的function..更改您的代码:

 function getRunId() { var result = counters.findOne({_id: 'Run_ID'}, function(err, resp) { if(err) { console.log(err); } console.log('Seq: ' + resp.sequence); // Console Output = Seq: 1234 return resp.sequence; }); return result; //<-- return result of your function is here }; var currentRunId = getRunId(); console.log('Run_ID: ' + currentRunId);