- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在 Node 中工作并尝试从我的数据库中加载下一个序列。我可以在函数内访问数据库、加载和返回序列,但无法在函数外访问它。
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
我已经检查了几页与使用回调、异步( Node 模块)、如何在函数中正确返回值等相关的 Stack Overflow 问题...但是没有一个能让我更接近于在功能。
在我的函数中使用 Mongo 查询会使这个问题变得更加复杂吗?
最佳答案
对于后来遇到此问题的任何人,start by reading this answer .
我已经处理过几次这个问题,所以我理解这种挫败感。您正在尝试通过这样做来混契约(Contract)步和异步代码:
var currentRunId = getRunId();
console.log('Run_ID: ' + currentRunId);
问题是 console.log('Run_ID: ' + currentRunId) 在调用 getRunID() 后立即调用,方法是将其分配给当前 RunID,而 getRunID() 在 console.log('Run_ID: ' + currentRunId) 之后解析), 导致 currentRunId 变量未定义。
但是,您有一些选择来处理这个问题。选项一是返回回调,并记录回调的结果。选项 2 是使用 ES6 promise。要使用选项 2,您需要 Node 版本 7,并且需要在代码中使用“use strict”。
这里有 3 个围绕函数 stub 构建的示例,该函数 stub 欺骗了 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
*/
通过保存到您的机器并运行来尝试一下:
Node 测试.js
Is this issue further complicated by the use of Mongo queries inside my function?
不,您只需要将查询结果传递给 promise 或回调,以便您可以在其他地方处理结果。
希望对您有所帮助!
编辑:OP 在评论中添加了以下代码,我将尝试对其进行分解和解决。
Unfortunately, using getRunIdB results in callback is not defined and using getRunIdC results in currentRunId is not defined
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
查看 an answer I gave to a similar question有关 JS 并发模型的更多详细信息。简单地说,getRunID() 函数正在执行异步代码。这意味着 getRunID() 不会被插入到消息队列中,消息队列决定了 javascript 执行的顺序,直到它的回调完成。因此,当您在 .then() 函数之外记录 currentRunID 时,结果是未定义的,因为 currentRunID 是未定义的。
我认为最终 OP 试图做的是导出函数的结果,以便可以用这些结果完成某些事情,这需要在回调中完成,如下所示:
getRunId.then(function (res) {
// Do stuff with the run ID here.
})
关于javascript - 函数返回不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41067943/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!