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?

Benutzer-Avatar
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.PrintNearestStore wird 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 hingerichtet Vor 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)

Benutzer-Avatar
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
  //
};

1158820cookie-checkKorrigieren Sie den Export der asynchronen Funktion in node.js

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy