Korrigieren Sie den Export der asynchronen Funktion in node.js
Lesezeit: 5 Minuten
Ich hatte mein benutzerdefiniertes Modul mit folgendem Code:
module.exports.PrintNearestStore = async function PrintNearestStore(session, lat, lon) {
...
}
Es hat gut funktioniert, wenn die Funktion außerhalb meines Moduls aufgerufen wurde. Wenn ich jedoch innerhalb aufgerufen habe, wurde beim Ausführen ein Fehler angezeigt:
(Knoten: 24372) UnhandledPromiseRejectionWarning: Unhandled Promise Rejection (Ablehnungs-ID: 1): ReferenceError: PrintNearestStore ist nicht definiert
Als ich die Syntax geändert habe zu:
module.exports.PrintNearestStore = PrintNearestStore;
var PrintNearestStore = async function(session, lat, lon) {
}
Es begann innerhalb des Moduls gut zu funktionieren, schlägt jedoch außerhalb des Moduls fehl – ich habe einen Fehler erhalten:
(Knoten: 32422) UnhandledPromiseRejectionWarning: Nicht behandelte Zusageablehnung (Ablehnungs-ID: 1): TypeError: mymodule.PrintNearestStore ist keine Funktion
Also habe ich den Code geändert in:
module.exports.PrintNearestStore = async function(session, lat, lon) {
await PrintNearestStore(session, lat, lon);
}
var PrintNearestStore = async function(session, lat, lon) {
...
}
Und jetzt funktioniert es in allen Fällen: innen und außen. Möchten Sie jedoch Semantik verstehen und ob es einen schöneren und kürzeren Weg gibt, sie zu schreiben? Wie man richtig definiert und verwendet asynchron funktionieren beide: innerhalb und außerhalb (Export) Modul?
Felix Klinge
Dies hat nicht wirklich etwas mit asynchronen Funktionen speziell zu tun. Wenn Sie eine Funktion intern aufrufen möchten und Exportiere es, definiere es Erste und dann exportieren.
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;
Erklärung der Probleme bei deinen Versuchen:
module.exports.PrintNearestStore = async function PrintNearestStore(session, lat, lon) {
...
}
Dies definiert keine Funktion im Modul. Die Funktionsdefinition ist eine Funktion Ausdruck. Der Name eines Funktionsausdrucks erstellt nur eine Variable innerhalb der Funktion selbst. Einfacheres Beispiel:
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`
Siehe auch Benannte Funktionsausdrücke entmystifiziert. Sie könnten natürlich auf die Funktion verweisen, wenn Sie darauf verweisen würden module.exports.PrintNearestStore überall, überallhin, allerorts.
module.exports.PrintNearestStore = PrintNearestStore;
var PrintNearestStore = async function(session, lat, lon) {
}
Das ist fast OK. Das Problem ist, dass der Wert von PrintNearestStore ist undefined wenn Sie es zuweisen module.exports.PrintNearestStore. Die Reihenfolge der Ausführung ist:
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
Einfacheres Beispiel:
var foo = bar;
console.log(foo, bar); // logs `undefined`, `undefined` because `bar` is `undefined`
var bar = 21;
console.log(foo, bar); // logs `undefined`, `21`
Wenn Sie die Reihenfolge ändern, funktioniert es wie erwartet.
module.exports.PrintNearestStore = async function(session, lat, lon) {
await PrintNearestStore(session, lat, lon);
}
var PrintNearestStore = async function(session, lat, lon) {
...
}
Das funktioniert, weil Zu der Zeit die zugewiesene Funktion module.exports.PrintNearestStorewird ausgeführt, PrintNearestStore hat die Funktion als Wert.
Einfacheres Beispiel:
var foo = function() {
console.log(bar);
};
foo(); // logs `undefined`
var bar = 21;
foo(); // logs `21`
Danke, ich verstehe. Nur neu geordnete Funktionsdefinition (entfernt var) und module.exports jetzt – Funktionsdefinition zuerst. Ich sehe, dass für den internen Aufruf der Funktionsdefinition die Reihenfolge nicht wichtig ist: Ich habe den Funktionsaufruf VOR seiner Definition, aber für module.exports es ist wichtig.
– Alexej Konzewitsch
12. Oktober 2017 um 17:44 Uhr
@AlekseyKontsevich: FWIW, Linie A ist Vor Zeile B im Quellcode bedeutet nicht, dass Zeile A es ist hingerichtetVor Zeile B. Am Ende zählt nur die Reihenfolge der Ausführung. Natürlich muss die Funktionsdefinition ausgewertet werden, bevor die Funktion aufgerufen werden kann. Die Ausführungsreihenfolge ist jedoch in JS aufgrund des Hebens möglicherweise nicht offensichtlich.
– Felix Klinge
12. Oktober 2017 um 17:47 Uhr
Fehler beim ersten Fall: PrintNearestStore – Funktionsausdruck, daher ist dieser Name außerhalb nicht verfügbar.
Fehler im zweiten Fall: Variable verwenden, stattdessen Funktionsdeklaration. In diesem Fall wird die Deklaration der Variablen PrintNearestStore hochgezogen, sodass Sie diesen Namen verwenden können Vor Linie var PrintNearestStore = ...aber in diesem Fall Wert wäre nicht definiert.
Also, einfachste Lösung, ändern Sie die zweite Variante wie folgt:
module.exports.PrintNearestStore = PrintNearestStore;
async function PrintNearestStore(session, lat, lon) {
}
Funktioniert nicht: Dann müssen Sie die Funktionsdefinition zuerst setzen module.exports.
– Alexej Konzewitsch
12. Oktober 2017 um 17:45 Uhr
Wie ich oben sagte, bekam ich UnhandledPromiseRejectionWarning für einen solchen Code in Knoten 8.6. Dann habe ich die Funktionsdefinition an die erste Stelle gesetzt module.exports reparieren.
– Alexej Konzewitsch
13. Oktober 2017 um 14:49 Uhr
@AlekseyKontsevich, um Fehler in Ihrem Fall zu erkennen, sollten wir ein minimal reproduzierbares Beispiel haben, wie ich es oben angegeben habe
– Grundi
13. Oktober 2017 um 15:25 Uhr
Keine Sorge, alles ist bereits gelöst: siehe Antwort oben. Sie können Ihre löschen.
– Alexej Konzewitsch
13. Oktober 2017 um 15:33 Uhr
@AlekseyKontsevich Aufgrund des Hebens spielt es keine Rolle, wo Sie die Funktion platzieren.
– Samuel Lindblom
8. April 2020 um 17:24 Uhr
Eine Alternative wäre, so zu exportieren. // foo.js
export async function foo(){
console.log('I am greatest of all.'); // for the person who reads it, just say it.
}
dann verwenden Sie es in anderen Skripten wie
import { foo } from './foo'
foo();
export let handlePostStore = async (data) => {
console.log('post');
return data;
};
// to import
import { handlePostStore } from 'your_path_here';
// to call it
handlePostStore(data)
Manohar Reddy Poreddy
Einige Beispiele:
module.exports.func1 = async function func1(id) { // name is preferred by linter
//
};
module.exports.func1 = async function (id) { // ok
//
};
module.exports.func1 = async (id) => { // simpler
//
};
11588200cookie-checkKorrigieren Sie den Export der asynchronen Funktion in node.jsyes