Question 1: Is JS synchronous?

Yes, JS is single-threaded and can only be executed synchronously (queued).

Why is JS asynchronous

Without asynchrony, code can only be executed from top to bottom, and in case the previous line takes too long to parse, the code below will be blocked. For users, this can mean gridlock, resulting in a poor user experience.

Question 3: How to achieve asynchronous JS single thread

Asynchrony is achieved through event loops

Console. log(111) setTimeout(()=>{console.log(222)},0) console.log(333) 111, 333,222 is displayedCopy the code

The function in setTimeout is not executed immediately, but delayed for a period of time until certain conditions are met. This kind of code is called asynchronous code.

The execution mechanism of JS is

  • First determine whether the JS code is synchronous or asynchronous, synchronous will enter the main process, asynchronous will enter the Event table
  • Asynchronous tasks register functions in the Event Table and are pushed to the Event Queue when triggering conditions are met
  • The synchronous task enters the main thread and executes until the main thread is idle. Then the event queue is checked to see if there are asynchronous tasks that can be executed. If there are asynchronous tasks, they are pushed to the main process

The above three steps are executed in a loop called the Event loop

Conclusion: Synchronization can guarantee the same order, but it is easy to cause blocking; Asynchrony solves the blocking problem, but changes the ordering, writing your code to suit your needs.

1. Serial execution and parallel execution of JS asynchronous functions

  • Serial refers to multiple tasks, each task is executed in sequence, and the next task can be performed only after one task is completed
  • Parallelism means that multiple tasks can be executed at the same time, and asynchrony is a prerequisite for the parallelism of multiple tasks
Var series= function (arr, callback) {var counter = 0; var process = function () { if (counter < arr.length) { var fun = arr[counter++]; if (fun) fun(process); } else { if (callback) callback(); } } process(); }Copy the code
Var parallel= function (arr,callback) {var counter = arr.length; var process = function () { if (! --counter) { if (callback) callback(); } } if (counter == 0) { if (callback) callback(); } else { arr.forEach(function (fun) { if (fun) fun(process); }); }}Copy the code

2. How do I serial implement promises

  • A simple example of promise.all
const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(111)
  }, 2500)
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(222)
  }, 3000)
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(333)
  }, 1000)
})

Promise.all([p1, p2, p3]).then(res => console.log('all', res)) // [111, 222, 333]
Promise.race([p1, p2, p3]).then(res => console.log('race', res)) // 333
Copy the code
  • Promise provides promise.all (), promise.race (), promise.allsettled ()
  • This can be handled with promise.all if run in parallel
  • If you want to run it serially, you can use array reduce to handle it
const fn1 = function(arg) { console.log('fn1', arg) return Promise.resolve(111) } const fn2 = function(arg) { console.log('fn2', Arg) // return promise. reject(new Error(' Yo, Error ')) return promise.resolve (222)} const fn3 = function(arg) {console.log('fn3', arg) return Promise.resolve(333) } const serialPromise = function(promises) { promises.reduce((prev, next) => prev.then(prevVal => next(prevVal)).catch(next()), Promise.resolve()) } serialPromise([fn1, fn2, Fn3]) // If there is a reject (reject), the reject (reject) is executed twice.Copy the code