Gemäß der Verheißungsspezifikation wird ein Versprechungs- oder Ablehnungs-Handler immer asynchron aufgerufen, nachdem die Ereignisschleife ihren aktuellen Zyklus beendet hat. Daher wird p12
nicht sofort aufgelöst, obwohl die Argumente dafür alle aufgelöste Versprechen sind. Daher wird es erst kurz nach Beendigung dieser Ereignisschleife aufgelöst. Dies erklärt, warum Ihre erste Aussage:
console.log(p12);
zeigt, dass das Versprechen noch „offen“. Es ist aktuell .then()
Handler (falls vorhanden) wurden noch nicht aufgerufen. Sobald jedoch der aktuelle Code-Thread fertig ausgeführt ist und die Steuerung zum nächsten Event in der Event-Queue zurückkehrt, wird das Versprechen gelöst und Ihr setTimeout()
sieht es dann als aufgelöst an. Diese
ist für Anrufer aus Konsistenzgründen getan, so dass .then()
Handler konsequent auf eine asynchrone Weise aufgerufen werden, egal, ob das Versprechen wurde bereits gelöst oder ist noch nicht gelöst. Dadurch kann der aufrufende Code immer konsistent codieren, ohne sich darüber Gedanken machen zu müssen, ob das Versprechen bereits gelöst sein könnte. In allen Fällen werden .then()
Handler aufgerufen, nachdem der aktuelle Stack abgewickelt und beendet ist.
Vom Promises/A+ specification:
onFulfilled oder onRejected darf nicht aufgerufen werden, bis die Ausführung Kontextstapel nur Plattform-Code enthält.
Hier bedeutet "Plattform-Code" Engine, Umgebung und Versprechen Implementierungscode. In der Praxis stellt diese Anforderung sicher, dass onFulfilled und onRejected asynchron ausgeführt werden, nach dem Ereignis Schleife drehen in der dann aufgerufen wird, und mit einem frischen Stapel. Dies kann entweder mit einem "Makro-Task" -Mechanismus wie setTimeout oder setImmediate oder mit einem "Mikro-Task" -Mechanismus wie MutationObserver oder process.nextTick implementiert werden. Da die Promise-Implementierung als Plattformcode betrachtet wird, kann sie selbst eine Task-Scheduling-Warteschlange oder "Trampolin" enthalten, in der die Handler aufgerufen werden.
Also das Ergebnis von all dem ist, dass Versprechen immer asynchron zu lösen, nachdem der aktuelle Thread der Ausführung beendet ist. Obwohl die internen Details etwas komplizierter sind (vielleicht mit Mikro-Aufgaben), können Sie logisch denken, dass ein Versprechen dadurch gelöst wird, dass eine Nachricht in die Ereigniswarteschlange gestellt wird, auf die jetzt gewartet werden soll. Und immer wenn die Ereigniswarteschlange beendet wird, was gerade ausgeführt wird, und dann die Versprechungen Handler ausgeführt werden, werden sie ausgeführt.
Versuchen Sie Ihre Resolve zu ändern: 'Promise.resolve (true);' – CodingGorilla