Zusammenfassung der Front-End-Interviewfragen (Algorithmus Teil 2) – die Ausgabereihenfolge von Promise und SetTimeout

Ausführungsreihenfolge von Makrotasks und Mikrotasks

Synchrone Aufgaben und asynchrone Aufgaben
JavaScript ist eine Single-Thread-Sprache, die jeweils nur eine Aufgabe ausführen kann. Dies führt dazu, dass die folgenden Aufgaben warten, bis die vorherigen Aufgaben abgeschlossen sind, bevor sie ausgeführt werden können. Wenn die vorherigen Aufgaben zeitaufwändig sind, führt dies dazu, dass die nachfolgenden Aufgaben ewig warten. Um dieses Problem zu lösen, erschienen in JS synchrone Aufgaben und asynchrone Aufgaben.

(1) Synchrone Aufgaben
Die Aufgaben, die zur Ausführung im Hauptthread in die Warteschlange gestellt werden, können die nächste Aufgabe erst ausführen, nachdem die vorherige Aufgabe abgeschlossen ist, und bilden so einen Ausführungsstapel.

(2) Asynchrone Aufgaben
gelangen nicht in den Hauptthread, sondern in die Aufgabenwarteschlange. Wenn die Aufgaben im Hauptthread ausgeführt werden, werden die Aufgaben aus der Aufgabenwarteschlange entnommen und zur Ausführung in den Hauptthread gestellt. Da der Hauptthread wiederholt Aufgaben abruft, Aufgaben ausführt, abruft und erneut ausführt, wird dieser Mechanismus als Ereignisschleife (Ereignisschleife) bezeichnet.

Beispiel für eine Ausführungssequenz

 1. Solange das neue Promise-Ereignis eingerichtet ist, wird der darin enthaltene Code sofort ausgeführt.
2. Die Codes von Promise.then() und Process.nextTick() werden am Ende der aktuellen Runde der „Ereignisschleife“ ausgeführt ";
3. setTimeoutd(fn, 0) Der Code von wird zu Beginn der nächsten Runde der „Ereignisschleife" ausgeführt;
4. Schließlich wird der Code von setTimeout(fn,1000) ausgeführt.

setTimeout(function () {
	var np =new  Promise(function (resolve,reject) {
		console.log(1)
		resolve()
	})
	np.then(_=>{
		console.log(2)
	})
	console.log(3)
},1000)
 
var pro = new Promise((resolve, reject) => {
	console.log(5)
	resolve()
}).then(_=>{
	setTimeout(function () {
		console.log(6)
	},0)
	return 7;
}).then(n=>{
	console.log(n)
})
console.log(4)
//执行结果 5  4  7  6  1  3  2

js führt zuerst  synchrone Aufgaben  wie console.log() in der Frage aus, führt dann console.log() im neuen Promise aus, sucht dann in asynchronen Aufgaben nach
Mikrotask  -Versprechen.resolve.then() und sucht schließlich  in asynchronen Aufgaben nach Makros Aufgaben Aufgabe  setTimeout(), und schließlich endet die Ausführung.

// 整体script作为第一个宏任务进入主线程......0
      // 同步任务console.log直接执行
      console.log('1'); ......1
      async function first() {
        console.log('first函数'); ......3
      }
      // 宏任务最后执行
      setTimeout(() => {
        console.log('settimeout  2'); .......7
      }, 0);
      // .then微任务
      Promise.resolve().then(() => {
        console.log('promise  3'); ......5
      });
      // 遇到new Promise直接执行,遇到.then分配到微任务队列中
      new Promise((resolve, reject) => {
        // new Promise里面的输出直接执行
        console.log(4); ......2
        // resolve暂停跳出Promise
        resolve();
      }).then((res) => {
        console.log(5); ......6
      });
      // 调用first函数,输出
      first();
      // 同步任务直接输出
      console.log('6'); ......4
//输出顺序   1     4     first函数    6    promise 3    5   settimeout 2

 Warten und lösen unterbrechen das aktuelle Versprechen, bis andere asynchrone Aufgaben abgeschlossen sind, bevor die Ausführung fortgesetzt wird. Führen Sie beispielsweise nach der Lösung des neuen Versprechens in der Frage
nicht weiter nach unten aus, sondern suchen Sie nach anderen synchronen Aufgaben. Nachdem alle synchronen Aufgaben abgeschlossen sind, suchen Sie nach Mikroaufgaben in den asynchronen Aufgaben und führen Sie schließlich das neue Versprechen aus. Dann Mikrotasks und schließlich nach asynchronen Tasks suchen. Die Makrotask wird ausgeführt.

console.log(1);

async function asyFunction () {
    console.log(2);
    await console.log(3);
    await console.log(4);
    console.log(5);
    return 6
}

new Promise((resolve, reject) => {
    console.log(10);
    resolve();
}).then(res => {
    console.log(11);
})

console.log(7);

setTimeout(() => {
    console.log(8)
}, 0)

setTimeout(() => {
    console.log(9)
}, 1000)

asyFunction().then(res => { console.log(res) });
//输出结果  1 10 7 2 3 11 4 5 6 8 9

Schauen Sie sich den Code nacheinander an, schauen Sie sich nicht zuerst die nicht ausgeführten an, Promise.resolve().then(() ... Mikrotask, legen Sie ihn in den Heap; setTimeout-Makroaufgabe wird in den Heap gelegt, führen Sie async1 aus, Gehen Sie zurück und schauen Sie sich async1 und die Ausgabe 1 an. Warten wird implizit ein Versprechen generieren, den folgenden Code in Promise.then einfügen und sich selbst ausführen, also Ausgabe 2, 3 in den Heap legen; dann ausführen, Ausgabe 6; beide 3 und 4 sind dann, siehe Reihenfolge der Codeausführung, also 4, 3; schließlich Makroaufgabe 5

async function async1 () {
  console.log(1);
  const result = await async2();
  console.log(3);
}
async function async2 () {
  console.log(2);
}
Promise.resolve().then(() => {
  console.log(4);
});
setTimeout(() => {
  console.log(5);
});
async1();
console.log(6);
//结果 1  2  6  4   3   5

 Die setTimeout-Makroaufgabe wird in den Heap gelegt. Sehen Sie sich sie nicht an, bevor der Test ausgeführt wird. Geben Sie die Promise-Ausgabe 2 ein, stoßen Sie auf die Rückruffunktion (Mikroaufgabe) und legen Sie sie in den Heap. Gehen Sie nach unten, async2 wird nicht ausgeführt. Fahren Sie fort, führen Sie die Testausgabe 5 aus und warten Sie. Die folgende Funktion wird sofort ausgeführt, ein Versprechen wird implizit generiert und der folgende Code wird in Promise.then verpackt, um eine Mikrotask zu werden und in den Heap zu legen. Nachdem der Test ausgeführt wurde, fahren Sie fort um nach unten zu gehen und 4 auszugeben. Aufgaben und Mikroaufgaben werden nacheinander entsprechend der Ausführungsreihenfolge des Codes ausgeführt, und die Priorität von then ist höher als die von „final“ (das von „final“ und „async“ erstellte .then gehört zur Ebene des ersten Rückrufs , und das .then dahinter ist schließlich bereits der zweite
Rückruf, also wird er unten platziert In der Mikrotask der ersten Ebene), also zuerst 3, 6 und dann 8 ausgeben und nach der Ausführung der Mikrotask die Makrotask ausführen

setTimeout(function () {
  console.log('1');
});
async function test () {
  console.log('5')
  //隐式创建一个微任务 promise.then()
  await async2();
  console.log('6')
}
new Promise(function (resolve) {
  console.log('2');
  resolve();
}).then(function () {
  console.log('3');
}).finally(() => {
  console.log('8');
})
function async2 () {
  console.log('7');
}
test()
console.log('4');
//结果:2、5、7、4、3、6、8、1

おすすめ

転載: blog.csdn.net/Holly31/article/details/130778837