2017-10-12 143 views
2

我有我有下面的代码自定义模块:正确的异步函数引出

module.exports.PrintNearestStore = async function PrintNearestStore(session, lat, lon) { 
... 
} 

它工作得很好,如果叫我的模块之外的功能,但是,如果我叫我里面运行时遇到错误:

(node:24372) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): ReferenceError: PrintNearestStore is not defined

当我改变语法:

module.exports.PrintNearestStore = PrintNearestStore; 

var PrintNearestStore = async function(session, lat, lon) { 

} 

它开始做工精细的内部模块,但没有欧tside模块 - 我有错误:

(node:32422) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: mymodule.PrintNearestStore is not a function

所以我改变了代码:

module.exports.PrintNearestStore = async function(session, lat, lon) { 
    await PrintNearestStore(session, lat, lon); 
} 

var PrintNearestStore = async function(session, lat, lon) { 
... 
} 

而现在它在所有情况下工作:内部和外部。但是想要理解语义,并且如果有更美好更短的方式来编写它呢?如何正确定义和使用异步函数:内部和外部(出口)模块?

回答

7

这对于异步函数并没有什么特别的意义。如果你想在内部调用一个函数导出它,首先定义它然后导出它。

async function doStuff() { 
    // ... 
} 
// doStuff is defined inside the module so we can call it wherever we want 

// Export it to make it available outside 
module.exports.doStuff = doStuff; 

与你尝试的问题说明:

module.exports.PrintNearestStore = async function PrintNearestStore(session, lat, lon) { 
... 
} 

模块在此没有定义的功能。函数定义是一个函数表达式。函数表达式的名称只在函数本身内部创建一个变量。简单的例子:

var foo = function bar() { 
 
    console.log(typeof bar); // 'function' - works 
 
}; 
 
foo(); 
 
console.log(typeof foo); // 'function' - works 
 
console.log(typeof bar); // 'undefined' - there is no such variable `bar`

参见Named function expressions demystified。如果您在任何地方都参考module.exports.PrintNearestStore,您当然可以参考该功能。


module.exports.PrintNearestStore = PrintNearestStore; 

var PrintNearestStore = async function(session, lat, lon) { 

} 

这是几乎确定。问题是,当您将其分配给module.exports.PrintNearestStore时,PrintNearestStore的值为undefined。执行的顺序是:

var PrintNearestStore; // `undefined` by default 
// still `undefined`, hence `module.exports.PrintNearestStore` is `undefined` 
module.exports.PrintNearestStore = PrintNearestStore; 

PrintNearestStore = async function(session, lat, lon) {} 
// now has a function as value, but it's too late 

简单的例子:

var foo = bar; 
 
console.log(foo, bar); // logs `undefined`, `undefined` because `bar` is `undefined` 
 
var bar = 21; 
 
console.log(foo, bar); // logs `undefined`, `21`

如果你改变了顺序,预期它会工作。


module.exports.PrintNearestStore = async function(session, lat, lon) { 
    await PrintNearestStore(session, lat, lon); 
} 

var PrintNearestStore = async function(session, lat, lon) { 
... 
} 

因为的时候分配给module.exports.PrintNearestStore功能被执行这工作,PrintNearestStore具有的功能作为其值。

简单的例子:

var foo = function() { 
 
    console.log(bar); 
 
}; 
 
foo(); // logs `undefined` 
 
var bar = 21; 
 
foo(); // logs `21`

+0

谢谢你,我明白了。刚刚重新排序的函数定义(现在删除'var')和'module.exports' - 函数定义首先。我发现对于内部调用函数定义顺序并不重要:我在定义之前调用了函数,但是对于'module.exports'它很重要。 –

+2

@AlekseyKontsevich:FWIW,在源代码中*行B之前的行A *并不意味着行A *在*行B之前执行* *。最后,执行顺序是唯一重要的事情。当然,函数定义必须在函数调用之前进行评估。但是,由于吊装,JS的执行顺序可能不明显。 –

2

错误与第一种情况:PrintNearestStore - 功能表达,所以这个名字不可用外部。

第二种情况的错误:使用变量,而不是函数声明。在这种情况下,变量PrintNearestStore的声明被挂起,因此,您可以在行var PrintNearestStore = ...之前使用此名称,但在这种情况下值将为undefined

所以,简单的解决方案改变第二个变体是这样的:

module.exports.PrintNearestStore = PrintNearestStore; 

async function PrintNearestStore(session, lat, lon) { 

} 
+0

不起作用:首先需要放置函数定义,然后是'module.exports'。 –

+3

@AlekseyKontsevich,不,我的解决方案按预期工作:https://repl.it/M8Jn – Grundy

+0

正如我上面所说的,我在节点8.6中得到了'UnhandledPromiseRejectionWarning'这样的代码。我先把函数定义,然后'module.exports'来修复。 –