[07] Summary of knowledge of factory interview - JS asynchronous step

JS Asynchronous-Advanced

  • The JS asynchronization explained earlier is in the first-order application
  • This chapter focuses on the principles and advances of JS asynchronization
  • A little difficult for beginners, try to be as deep as possible

Main Contents of this Chapter

  • event loop
  • promise Advancement
  • async/await
  • Micro/Macro Tasks

Interview Questions Related to this Chapter

  • Describe the mechanism of event loop (event loop/event polling), which can be graphed
  • What are macro tasks and micro tasks, and what is the difference between them?
  • What are the three states of Promise?How to change

Scene Title

The connection between promise the N and catch

//Topic 1
Promise.resolve().then(() => {
	console.info(1)
}).catch(() => {
	console.info(2)
}).then(() => {
	console.info(3)
})
//Output: 1 3


//Question 2
Promise.resolve().then(() => {
	console.info(1)
	throw new Error('error1')
}).catch(() => {
	console.info(2)
}).then(() => {
	console.info(3)
})
//Output: 1 2 3

//Question 3
Promise.resolve().then(() => {
	console.info(1)
	throw new Error('error1')
}).catch(() => {
	console.info(2)
}).catch(() => {				//Here is catch
	console.info(3)
})
//Output: 1 2

async/await syntax

async function fn() {
	return 100
}
(async function () {
	const a = fn()			// ??
	const b = await fn()	// ??
})()

(async function () {
	console.info('start')
	const a = await 100
	console.info('a', a)
	const b = await Promise.resolve(200)
	console.info('b', b)
	const c = await Promise.reject(300)
	console.info('c', c)
	console.info('end')
})()//Execute, print out those

Order of promise and setTimeout

console.info(100)
setTimeout(() => {
	console.info(200)
})
Promise.resolve().then(() => {
	console.info(300)
})
console.info(400)

Additional async/await sequencing issues

async function async1 () {
	console.info('async1 start')
	await async2()
	console.info('async1 end')
}
async function async2 () {
	console.info('async2')
}
console.info('script start')
setTimeout(function () {
	console.info('setTimeout')
}, 0)

async1()

new Promise(function (resolve) {
	console.info('promise1')
	resolve()
}).then(function () {
	console.info('promise2')
})
console.info('script end')

Event loop (event loop/event polling)

  • JS is single-threaded
  • Asynchronization is based on callbacks
  • event loop is the implementation principle of asynchronous callback

How does JS execute?

  • From front to back, line by line
  • Stop execution of the following code if a line fails to execute
  • Execute synchronous code before asynchronous
console.info('Hi')

setTimeout(function cb1() {
	console.info('cb1')		//cb is callback
}, 5000)

console.info('Bye')

Start explaining the event loop process

  • Beginners may find it difficult to go as far as possible
  • The first time you explain, don't stop what you don't understand, you will repeat it three times
  • Don't skim over details, don't expand scope, the core is the event loop process

Summarize event loop process 1

  • Synchronize code, line by line in Call Stack
  • Encountered asynchronous, will first "record" the opportunity to wait (timer, network requests, etc.)
  • When it's time, move to Callback Queue

Summarize event loop process 2

  • Event Loop starts working if Call Stack is empty (that is, when synchronization code is executed)
  • Polling Find Callback Queue, Move to Call Stack if necessary to execute
  • Then continue polling (like a perpetual machine)

DOM events and event loop

  • JS is single threaded
  • Asynchronous (setTimeout, ajax, etc.) uses callbacks, based on event loop
  • DOM events also use callbacks, based on event loop
console.info('Hi')
setTimeout(function cb1() {
	console.info('cb1')		//cb is callback
}, 5000)
console.info('Bye')
<button id="btn1"></button>
<script>
	console.info('Hi')
	$('btn1').click(function (e) {
		console.info('button clicked')
	})
	console.info('Bye')
</script>

Promise

  • Three states:
    • pending,resolved,rejected
    • Pending -> resolved or pending -> rejected
    • Change is irreversible
  • The representation and change of state
    • pending state, does not trigger the then and catch
    • resolved state, triggering subsequent then callback functions
    • rejected state, triggering subsequent catch callback functions
  • The effect of the then and catch on the state

The N and catch change state

  • The n returns resolved normally, rejected if there is an error in it
  • catch returns resolved normally, rejected if there is an error
const p1 = Promise.resolve().then(() => {
	return 10
})
console.info('p1', p1)	//resolved triggers subsequent then callbacks
p1.then(() => {
	console.info('123')
})

const p2 = Promise.resolve().then(() => {
	throw new Error('then error')
})
console.info('p2', p2)	//reject triggers subsequent catch callbacks
p2.then(() => {
	console.info('456')
}).catch(err => {
	consoel.info('err100', err)
})

Promise Summary

  • Three states, state representation and change
  • The effect of the then and catch on the state (important)
  • Chained calls to the then and catch (common reference)

async/await

  • Asynchronous callback hell
  • Promise then catch chain call, but also based on callback functions
  • async/await is synchronous syntax, eliminating callback functions completely

Relationship between async/await and Proise

  • async/await is the ultimate weapon to eliminate asynchronous callbacks

  • But they are not mutually exclusive with Proise

  • Instead, they complement each other

  • Execute the async function and return a Promise object

  • await is equivalent to Promise's then

  • try...catch catches exceptions instead of Promise's catch

async function fn1() {
	//return 100
	return Promise.resolve(200)
}
const res1 = fn1()			//Executing the async function returns a promise object
console.info('res1', res1)	//promise object
res1.then(data => {
	console.info('data', data)	//200
})

!(async function () {
	const p1 = Promise.resolve(300)
	const data = await p1			//await is equivalent to Promise's then
	console.info('data', data)
})

The nature of asynchronism

  • async/await is the ultimate weapon to eliminate asynchronous callbacks
  • JS or single threaded, asynchronous, event loop based
  • async/await is just a grammatical sugar, but it is delicious!
async function async1 () {
	console.info('async1 start')		//2 Important
	await async2()						//undefined
	//Behind await, you can think of it as something in the callback.That is, asynchronous
	//Similar, event loop, settim(cb1)
	//setTimeout(function() {console.info('async1 end') })
	//Promise.resolve().then(() => {console.info('async1 end')})
	console.info('async1 end')		//5
}

async function async2 () {
	console.info('async2')		//3 Important
}
console.info('script start')	//1
async1()
console.info('script end')		//4

//The synchronization code has been executed (event loop)

for ... of

  • For... In (and forEach for) is a regular synchronous traversal
  • For... Of is often used for asynchronous traversal
function muti(num) {
	return new Promise(resolve => {
		setTimeout(() => {
			resolve(num * num)
		}, 1000)
	})
}

const nums = [1, 2, 3]
nums.forEach(async (i) => {
	const res = asait muti(i)
	console.info(res)			//Simultaneous printing after 1 second: 1, 4, 9
})

!(async function () {
	for (let i of nums) {
		const res = await muti(i)
		console.info(res)			//Output every second: 1, 4, 9
	}
})()

Summary of async/await

  • async/await resolves asynchronous callbacks and is a nice grammatical sugar
  • The relationship between async/await and Proise is important!
  • Use of for...of

Macro Task and Micro Task

  • What is a macro task and what is a micro task
    • Macro Tasks: setTimeout, setInterval, Ajax, DOM Events
    • Microtask: Promise async/await
    • Micro tasks execute earlier than macro tasks (remember first)
  • event loop and DOM rendering
  • Differences between micro and macro tasks
console.info(100)					//1
setTimeout(() => {
	console.info(200)				//4
})
Promise.resolve().then(() => {
	console.info(300)				//3
})
console.info(400)					//2

event loop and DOM rendering

  • Return to the process of event loop s again
  • JS is single-threaded and shares a thread with DOM rendering
  • When the JS executes, you have to leave some time for the DOM to render
const $p1 = $('<p>A piece of text</p>')
const $p2 = $('<p>A piece of text</p>')
const $p3 = $('<p>A piece of text</p>')

$('#container').append($p1).append($p2).append($p3)
console.info('length', $('#container').children().length)
alert('This time call stack End, DOM Structure updated, but rendering has not been triggered')
//(alert blocks js execution and DOM rendering for easy viewing)

Review the event loop process (increasing DOM rendering timing)

event loop and DOM rendering

  • Each Call Stack is emptied (i.e. the end of each poll), i.e. the synchronization task is completed
  • All opportunities for DOM re-rendering, DOM structure re-rendering if changed
  • Then trigger the next event loop again

Differences between micro and macro tasks

  • Macro Task: Triggered after DOM rendering, such as setTimeout
  • Microtask: triggered before DOM rendering, such as Promise
  • Demonstrate the phenomenon before investigating the principles
const $p1 = $('<p>A piece of text</p>')
const $p2 = $('<p>A piece of text</p>')
const $p3 = $('<p>A piece of text</p>')

$('#container').append($p1).append($p2).append($p3)

//Microtask: triggered before DOM rendering
Promise.resolve().then(() => {
	console.info('length1', $('#container').children().length)
	alert('Promise then')		//Does DOM render?NO
})

setTimeout(() => {
	console.info('length2', $('#container').children().length)	//3
	alert('setTimeout')		//Does DOM render?yes
})

Explain from event loop why microtasks execute earlier

Why?

  • Microtasks are specified in ES6 syntax
  • Macro tasks are specified by the browser

Micro and Macro Tasks - Summary

  • What are the macro tasks?What are microtasks?Microtask triggers earlier
  • Relationship between Micro Tasks, Macro Tasks and DOM Rendering
  • Micro Tasks, Macro Tasks, and DOM Rendering, in the event looop process
async function fn() {
	return 100
}
(async function () {
	const a = fn()			// ??
	const b = await fn()	// ??
})()


(async function () {
	console.info('start')
	const a = await 100
	console.info('a', a)
	const b = await Promise.resolve(200)
	console.info('b', b)
	const c = await Promise.reject(300)
	console.info('c', c)
	console.info('end')
})()

Order of promise and setTimeout

console.info(100)
setTimeout(() => {
	console.info(200)
})
Promise.resolve().then(() => {
	console.info(300)
})
console.info(400)

Additional async/await sequencing issues

async function async1 () {
	console.info('async1 start')
	await async2()
	console.info('async1 end')
}
async function async2 () {
	console.info('async2')
}
console.info('script start')
setTimeout(function () {
	console.info('setTimeout')
}, 0)

//Connect the left code and read it together
async1()

new Promise (function (resolve) {
	console.info('promise1')
	resolve()
}).then(function () {
	console.info('promise2')
})
console.info('script end')

Keywords: Javascript Front-end Vue.js Interview

Added by galmar on Fri, 03 Sep 2021 01:01:16 +0300