Heim  >  Artikel  >  Web-Frontend  >  Lassen Sie uns darüber sprechen, welche „chemischen Reaktionen“ ablaufen, wenn „await“ in JS-Schleifen verwendet wird

Lassen Sie uns darüber sprechen, welche „chemischen Reaktionen“ ablaufen, wenn „await“ in JS-Schleifen verwendet wird

藏色散人
藏色散人nach vorne
2023-03-02 17:22:281691Durchsuche

Dieser Artikel vermittelt Ihnen relevantes Wissen über JavaScript-Schleifen. Er befasst sich hauptsächlich mit der Verwendung von „await“ in js-Schleifen und der Ergebnisanalyse. Ich hoffe, dass er für alle hilfreich ist.

Vorwort

Wie ist diese Frage entstanden? Als ich eines Tages etwas über asynchrones Wissen lernte, stieß ich auf eine Frage wie diese: Verwenden Sie Promise, um jede Sekunde einen Wert in einem Array auszugeben Ich habe gedacht, dass es auch gelöst werden kann, wenn ich nach der Ausgabe des Werts in einer Schleife eine Sekunde lang anhalte, also habe ich den folgenden Code:

const arr = [1, 2, 3]
arr.reduce((pre, cur) => {
  return pre.then(() => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(console.log(cur))
      }, 1000);
    })
  })
}, Promise.resolve())

Das Druckergebnis entspricht auch den Erwartungen. Hier habe ich die erste Frage generiert: Nicht Muss es nicht mit Async verwendet werden? Wie kann es hier alleine verwendet werden? (Wenn Sie mir nicht glauben, versuchen Sie, den Code in die Browserkonsole einzufügen.)

Dann habe ich for in forEach geändert und festgestellt, dass der Effekt überhaupt nicht erzielt wurde. Die zweite Frage stellte sich: Warum ist das Warten in forEach fehlgeschlagen?

Promise.resolve().then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(1))
    }, 1000);
  })
}).then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(2))
    }, 1000);
  })
}).then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(3))
    }, 1000);
  })
})

Mit diesen beiden Fragen beginnen Sie zu studieren und nach Antworten zu suchen.

await in der for-Schleife

Ich erinnere mich, dass es beim Lernen von async/await ein Sprichwort gab, dass „await“ nur mit async verwendet werden kann. Tatsächlich ist dieser Satz nicht falsch. Warum kann ich dann direkt in die Browserkonsole schreiben? Wenn wir Code im Editor schreiben, müssen wir async verwenden. Das ist also ein Witz, haha, aber wenn ich auf etwas stoße Ich verstehe nicht, ich muss über eine andere Richtung nachdenken. Okay, wie oben erwähnt, spielt das Warten eine Rolle, indem es JS ermöglicht, zu warten, bis das Verarbeitungsergebnis per Versprechen zurückgegeben wird, und dann mit der Ausführung fortzufahren. Dann ist es auch möglich.

const arr = [1, 2, 3]
const sleep = (ms) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve()
    }, ms)
  })
}
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
  await sleep(1000)
}
arr.forEach(async item => {
  console.log(item);
  await sleep(1000)
})

Die Ergebnisse sind auch möglich entsprechend den Erwartungen. Sie können „await“ in der Schleife verwenden und den Effekt erzielen

await in der forEach-Schleife

Wie am Anfang wird der erwartete Effekt in „forEach“ nicht erreicht; forEach ist ungültig.

Dann sind die Erklärungen, die ich gesehen habe, wie folgt:

forEach in JavaScript unterstützt weder Promise Awareness noch Async und Wait, sodass Sie in forEach nicht verwenden können.

    map/forEach wird intern in Kombination mit einem Rückruf verwendet, um die Funktion auszuführen. Warten wartet nicht auf die Ausführung des Rückrufs.
  • forEach unterstützt nur synchronen Code.
  • Die zweite Möglichkeit, den Pseudocode in Zukunft zu vereinfachen lautet wie folgt:
  •  <script>  
       const arr = [1, 2, 3]
       const sleep = (ms) => {
         return new Promise((resolve, reject) => {
           setTimeout(() => {
             resolve()
           }, ms)
         })
       }
       const logByOneSecond = async () => {
         for (let i = 0; i < arr.length; i++) {
           console.log(arr[i]);
           await sleep(1000)
         }
       }   
       logByOneSecond()
     </script>

    map/forEach ist eine einfache Ausführungsrückruffunktion und behandelt keine asynchronen Situationen. Das heißt: map/forEach erstellt mehrere Rückruffunktionen gleichzeitig und fügt mehrere Rückruffunktionen mit ihrer eigenen Asynchronität und Wartezeit hinzu, wie unten gezeigt.

    const logByForof = async () => {
      for (const item of arr) {
        console.log(item);
        await sleep(1000)
      }    
    }
    logByForof()
  • Jede Funktion ist unabhängig, und die Rückrufe der anderen sind ebenfalls unabhängig von der Anforderung ist asynchron, sie stehen in keinem Zusammenhang und die Reihenfolge kann nicht garantiert werden

Zusammenfassung

Überprüfte die Verwendung von async/await in Schleifenanweisungen. Bei gewöhnlichen for-Schleifen sind alle Wartevorgänge serielle Aufrufe. Ja, das können Sie Verwenden Sie es mit Zuversicht, einschließlich while, for-in, for-of usw.; Array-Methoden mit Rückrufen wie forEach, Map, Filter, Reduce usw. haben jedoch viele Nebenwirkungen, daher ist es am besten, dies nicht zu tun Verwenden Sie „await“.

【Empfohlenes Lernen: Javascript-Tutorial für Fortgeschrittene

Das obige ist der detaillierte Inhalt vonLassen Sie uns darüber sprechen, welche „chemischen Reaktionen“ ablaufen, wenn „await“ in JS-Schleifen verwendet wird. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen