Start · Sprachen · JavaScript · Referenz · SerialPort.close()

SerialPort.close()

Methode

Schließt einen geöffneten seriellen Port und gibt ein <code>Promise</code> zurück, das erfüllt wird, sobald der Port vollständig geschlossen ist.

seit JavaScript Chromium 89+ (Chrome, Edge, Opera, nur Desktop); n Kategorie: webapi

Signatur

SerialPort.prototype.close()

Beschreibung

Mit close() beenden Sie die Verbindung zu einem seriellen Gerät (z. B. Arduino, Mikrocontroller, GPS-Empfänger oder Barcode-Scanner), die Sie vorher mit SerialPort.open() geöffnet haben. Der Browser gibt dabei den Port für das Betriebssystem frei. Danach können andere Anwendungen oder ein neuer Aufruf von open() den Port wieder verwenden.

Wichtig ist die Reihenfolge: close() funktioniert nur, wenn weder port.readable noch port.writable gesperrt sind. Hält ein ReadableStreamDefaultReader oder WritableStreamDefaultWriter die Sperre, wird das Promise abgelehnt. Brechen Sie deshalb zuerst laufende Lesevorgänge mit reader.cancel() ab, rufen Sie releaseLock() auf Reader und Writer auf und warten Sie auf Pipes (pipeTo()). Erst dann schließen Sie den Port.

Beim Schließen werden gepufferte, noch nicht gesendete Daten verworfen. Warten Sie also auf writer.close() bzw. auf ausstehende write()-Promises, wenn alle Daten ankommen müssen. Nach dem Schließen sind port.readable und port.writable wieder null.

Rückgabewert

Typ
Promise<undefined>
Beschreibung
Ein Promise, das mit undefined erfüllt wird, sobald der Port geschlossen ist. Es wird abgelehnt, wenn der Port nicht geöffnet ist (InvalidStateError) oder wenn readable/writable noch durch einen Reader oder Writer gesperrt sind (TypeError).

Beispiele

Port öffnen, Befehl senden und wieder schließen

const sendCommand = async () => {
  // Muss durch eine Benutzeraktion ausgelöst werden (z. B. Klick)
  const port = await navigator.serial.requestPort();
  await port.open({ baudRate: 9600 });

  const writer = port.writable.getWriter();
  await writer.write(new TextEncoder().encode('LED ON\n'));
  writer.releaseLock(); // Sperre freigeben, sonst schlägt close() fehl

  await port.close();
  console.log('Port geschlossen, writable =', port.writable);
};

document.querySelector('#send').addEventListener('click', sendCommand);
Port geschlossen, writable = null

Laufende Leseschleife sauber beenden

let port;
let reader;
let keepReading = true;

const readLoop = async () => {
  while (port.readable && keepReading) {
    reader = port.readable.getReader();
    try {
      while (true) {
        const { value, done } = await reader.read();
        if (done) break; // durch reader.cancel() ausgelöst
        console.log('Empfangen:', value.length, 'Bytes');
      }
    } catch (err) {
      console.error('Lesefehler:', err);
    } finally {
      reader.releaseLock();
    }
  }
  await port.close();
  console.log('Port geschlossen');
};

document.querySelector('#connect').addEventListener('click', async () => {
  port = await navigator.serial.requestPort();
  await port.open({ baudRate: 115200 });
  readLoop();
});

document.querySelector('#disconnect').addEventListener('click', async () => {
  keepReading = false;
  await reader?.cancel(); // beendet das ausstehende read()
});
Port geschlossen

Schließen bei Verwendung von TextDecoderStream/pipeTo

const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });

const decoder = new TextDecoderStream();
const readableClosed = port.readable.pipeTo(decoder.writable);
const reader = decoder.readable.getReader();

// ... später: Verbindung trennen
const disconnect = async () => {
  await reader.cancel();
  // Die Pipe wird durch das Abbrechen abgelehnt – das ist erwartet
  await readableClosed.catch(() => {});
  await port.close();
  console.log('Verbindung getrennt');
};

await disconnect();
Verbindung getrennt

// Wichtig · Fallstricke

  • Häufigster Fehler: TypeError: Failed to execute 'close' on 'SerialPort': Cannot cancel a locked stream. Das bedeutet, dass ein Reader oder Writer noch aktiv ist. Rufen Sie vorher reader.cancel() und releaseLock() auf und warten Sie auf Pipes von pipeTo().
  • Ein Aufruf von close() auf einem Port, der nicht geöffnet ist, lehnt das Promise mit InvalidStateError ab. Prüfen Sie z. B. mit port.readable !== null, ob der Port offen ist.
  • Daten, die noch nicht gesendet wurden, gehen verloren. Warten Sie deshalb auf ausstehende writer.write()- bzw. writer.close()-Promises.
  • Wird das Gerät physisch getrennt, löst der Browser das Ereignis disconnect aus und schließt den Port selbst. Ein anschließender Aufruf von close() ist dann nicht mehr nötig.
  • Kompatibilität: Die Web Serial API gibt es nur in Chromium-basierten Desktop-Browsern (ab Chrome/Edge 89). Sie funktioniert nur in einem sicheren Kontext (HTTPS) und steht in Fenstern und Dedicated Workern zur Verfügung. Firefox und Safari unterstützen sie nicht. Prüfen Sie die Unterstützung mit 'serial' in navigator.
  • Über eine Permissions-Policy (serial) kann die API z. B. in iframes gesperrt sein.