Ich habe eine asynchrone Funktion, die true oder false zurückgibt. Es sieht so aus:

class User {
  async canManageGroup(group) {
    if (typeof group === 'number') {
      // group - id
      group = await getGroupById(group)
    } // else group is already loaded from DB

    return this.id === group.manager.id
  }
}

Wenn der Parameter group die ID der Gruppe ist, ruft die Funktion die Datenbank asynchron auf, sodass die Funktion canManageGroup asynchron ausgeführt wird. Wenn der Parameter group jedoch ein Gruppenmodell ist, ruft die Funktion nur return this.id === group.manager.id auf oder wird synchron ausgeführt. Ist es eine gute Praxis, Code auf diese Weise zu schreiben? Oder sollte ich synchronen Code in asynchronen Code umwandeln?

function makeAsync(cb) {
  return new Promise(resolve => setImmediate(() => resolve(cb())))
}

class User {
  async canManageGroup(group) {
    if (typeof group === 'number') {
      // group - id
      group = await getGroupById(group)
    } // else group is already loaded from DB

    return await makeAsync(() => this.id === group.manager.id)
  }
}
2
Oleh Misarosh 18 Apr. 2018 im 15:57

3 Antworten

Beste Antwort

Basierend auf Ihrem Kommentar zu einer der Antworten sind Sie aufgrund der Antwort auf die Frage Wie erstellen Sie benutzerdefinierte asynchrone Funktionen in node.js?

Das Problem ist, dass diese Funktion inkonsistent ist: Manchmal ist sie asynchron, manchmal nicht. Angenommen, Sie haben einen Verbraucher wie diesen:

In js-Umgebungen wie nodejs ist es üblich, dass der Rückruf , der asynchron ausgeführt werden kann, immer als asynchron bezeichnet wird, unabhängig davon, ob der tatsächliche Code wirklich asynchron war.

Sie fragen sich also, ob der folgende Code diese gängige Praxis verletzt.

async function doSomething() {
  return true
}

doSomething()
.then(res => {
   console.log(res)
})

Dies ist nicht der Fall, da Sie sich hier mit Versprechen befassen und ein Versprechen sofort aufgelöst werden darf. Der obige Code ist im Grunde der gleiche, als würden Sie schreiben:

Promise.resolve(true)
.then(res => {
   console.log(res)
})

Das asynchrone Verhalten wird im Verkettungsteil (then / catch) sichergestellt. Der Rückruf, den Sie an then / catch übergeben, wird als asynchron bezeichnet:

async function doSomething() {
  return true
}

console.log('before');

doSomething()
  .then(res => {
    console.log('with in callback')
  })

console.log('after');

Wie Sie sehen können, ist die Reihenfolge der Protokolle:

vor
nach
mit in Rückruf

Dies ist also in derselben Reihenfolge, die Sie von einer regulären asynchronen Rückruffunktion erwarten würden.

0
t.niese 18 Apr. 2018 im 15:25

Sie können das erste Beispiel ohne Probleme verwenden.

Wenn Sie async verwenden, gibt Ihre Funktion ein Promise zurück. Wenn Ihr Code sync lautet, lautet der Status des zurückgegebenen Versprechens resolved und es ist sicher, versprechungsbezogenen Code darauf auszuführen (then, catch usw. ).

Beispielsweise:

async function truePromise() {
  return true;
}

truePromise().then(function(value){
  console.log("Promise value:", value);
});

Funktioniert einfach :)

Solltest du es tun?

Ja. Es ist in Ordnung und funktioniert dank des Schlüsselworts async in Ordnung.

Was Sie NICHT tun dürfen, ist Folgendes:

function dontDoIt(doSync) {
  if (doSync) return false;
  return Promise.resolve(false)
}

Warum? Weil:

  • Wenn doSync wahr ist, wird false zurückgegeben (d. h. ein Boolescher Wert).
  • Wenn doSync falsch ist, wird ein Promise zurückgegeben, das in false aufgelöst wird.

Das ist ein RIESIGER Unterschied.

Warum?

Ihre Funktion gibt manchmal ein Versprechen und manchmal einen Booleschen Wert zurück. Es ist inkonsistent.

  • doSync (true) ist ein Boolescher Wert. Sie können weder await noch .then verwenden.
  • doSync (false) ist ein Versprechen, das Sie abwarten und dann verwenden können.
1
muZk 18 Apr. 2018 im 17:36

Der erste ist richtig. Es ist nicht erforderlich, etwas zur Asynchronisierung zu zwingen, wenn dies nicht erforderlich ist. Die Kontextumschaltung ist nicht kostenlos. Wenn Sie also nicht auf den Abschluss warten müssen, versuchen Sie nicht, sie zu erstellen.

0
Matti Price 18 Apr. 2018 im 13:04