在node.js中更正异步函数导出

Ale*_*ich 41 javascript node.js async-await

我的自定义模块包含以下代码:

module.exports.PrintNearestStore = async function PrintNearestStore(session, lat, lon) {
...
}
Run Code Online (Sandbox Code Playgroud)

如果在我的模块外部调用函数,它工作正常,但如果我调用内部运行时出错:

(node:24372)UnhandledPromiseRejectionWarning:未处理的promise promise(拒绝id:1):ReferenceError:PrintNearestStore未定义

当我将语法更改为:

module.exports.PrintNearestStore = PrintNearestStore;

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

}
Run Code Online (Sandbox Code Playgroud)

它开始在模块内部工作正常,但在模块外部失败 - 我收到错误:

(node:32422)UnhandledPromiseRejectionWarning:未处理的promise promise(拒绝id:1):TypeError:mymodule.PrintNearestStore不是函数

所以我把代码更改为:

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

var PrintNearestStore = async function(session, lat, lon) {
...
}
Run Code Online (Sandbox Code Playgroud)

现在它适用于所有情况:内部和外部.但是想要了解语义,是否有更美观,更短的写作方式?如何正确定义和使用异步函数:内部和外部(导出)模块?

Fel*_*ing 57

这与异步函数没有任何关系.如果要在内部调用函数并将其导出,请先定义它然后将其导出.

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;
Run Code Online (Sandbox Code Playgroud)

解释您尝试的问题:

module.exports.PrintNearestStore = async function PrintNearestStore(session, lat, lon) {
...
}
Run Code Online (Sandbox Code Playgroud)

这不会在模块中定义功能.函数定义是函数表达式.函数表达式的名称仅在函数本身内创建变量.更简单的例子:

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`
Run Code Online (Sandbox Code Playgroud)

另请参见命名函数表达式揭秘.如果你在module.exports.PrintNearestStore任何地方都提到,你当然可以参考这个功能.


module.exports.PrintNearestStore = PrintNearestStore;

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

}
Run Code Online (Sandbox Code Playgroud)

几乎没问题.问题是,当您指定它时,值PrintNearestStore是.执行顺序是:undefinedmodule.exports.PrintNearestStore

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
Run Code Online (Sandbox Code Playgroud)

更简单的例子:

var foo = bar;
console.log(foo, bar); // logs `undefined`, `undefined` because `bar` is `undefined`
var bar = 21;
console.log(foo, bar); // logs `undefined`, `21`
Run Code Online (Sandbox Code Playgroud)

如果您更改了订单,它将按预期工作.


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

var PrintNearestStore = async function(session, lat, lon) {
...
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为module.exports.PrintNearestStore 执行分配的函数时,PrintNearestStore将函数作为其值.

更简单的例子:

var foo = function() {
  console.log(bar);
};
foo(); // logs `undefined`
var bar = 21;
foo(); // logs `21`
Run Code Online (Sandbox Code Playgroud)

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

raj*_*iya 9

另一种选择是像这样导出。// foo.js

export async function foo(){ 
 console.log('I am greatest of all.'); // for the person who reads it, just say it.
}
Run Code Online (Sandbox Code Playgroud)

然后在其他脚本中使用它,例如

import { foo } from './foo'

foo();
Run Code Online (Sandbox Code Playgroud)


Gru*_*ndy 5

第一种情况错误:PrintNearestStore- 函数表达式,因此该名称在外部不可用。

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

因此,最简单的解决方案改变第二个变体,如下所示:

module.exports.PrintNearestStore = PrintNearestStore;

async function PrintNearestStore(session, lat, lon) {

}
Run Code Online (Sandbox Code Playgroud)

  • 不起作用:需要先放置函数定义,然后放置“module.exports”。 (2认同)