JavaScript asynchronous programming _035

Posted by npereira on Sun, 13 Oct 2019 08:11:31 +0200

JavaScript asynchronous programming

An interview question

for(var i = 0; i < 3; i++) {
   setTimeout(function() {
       console.log('timeout' + i);
   })
}

new Promise(function(resolve) {
    console.log('promise1');
    for(var i = 0; i < 1000; i++) {
        i == 99 && resolve();
    }
    console.log('promise2');
}).then(function() {
    console.log('then1');
})

console.log('global1');


promise1
promise2
global1
then1
3 timeout3

JavaScript Single Thread

In a page of browser, the JS program of this page has only one thread, so it is called single thread. Because it is a single thread, the execution order of the program is from top to bottom, and only one piece of code can be executed at the same time.

Browser Multiprocess

  • Browsers are multi-process
  • The browser works because the system allocates resources (cpu, memory) to its processes.
  • Simply understand that every Tab page opened is equivalent to creating a separate browser process.
  • The browser's rendering process is multithreaded

    • GUI Rendering Thread
    • JS Engine Thread
    • Event-triggered threads
    • Timing Trigger Thread
    • Asynchronous http request threads

Browser Rendering Process Diagram:

Asynchronous mechanism

 for (var i = 0; i < 5; i ++) {
        setTimeout(function(){
            console.log(i);
        }, 0);
    }
    console.log(i);
    //5 ; 5 ; 5 ; 5; 5

Callback function

This is the most basic method of asynchronous programming.

Suppose there are two functions f1 and f2, the latter waiting for the results of the former.

  f1();

  f2();

If F1 is a time-consuming task, we can consider rewriting F1 and writing f2 as a callback function of f1. "

  function f1(callback){
    setTimeout(function () {
      // f1 task code
      callback();
    }, 1000);
  }

The execution code becomes as follows:

 f1(f2);

In this way, we turn synchronous operation into asynchronous operation, f1 will not block the operation of the program, equivalent to the main logic of the first execution of the program, will delay the execution of time-consuming operations.

The advantages of callback function are simple, easy to understand and deploy, the disadvantages are not conducive to the reading and maintenance of the code, the high Coupling between various parts, the process will be very confusing, and each task can only specify one callback function.

Publish subscribe

Publish-Subscribe mode, also known as Observer mode, defines a one-to-many dependency, that is, when the state of an object changes, all objects that depend on it are notified.

let yourMsg = {};
yourMsg.peopleList = [];
yourMsg.listen = function (fn) {
    this.peopleList.push(fn);
}
yourMsg.triger = function () {
    for(var i = 0,fn;fn=this.peopleList[i++];){
        fn.apply(this,arguments);
    }
}

yourMsg.listen(function (name) {
    console.log(`${name}I got your message.`);
})
yourMsg.listen(function (name) {
    console.log('Ha-ha');
})

yourMsg.triger('Zhang San');
yourMsg.triger('Li Si');

Promise

Promise is an object that represents the final completion or failure of an asynchronous operation.

The most direct benefit of Promise is chaining.

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* Successful asynchronous operation */){
    resolve(value);
  } else {
    reject(error);
  }
});

Generators/ yield

Generator

function* Hello() {
    yield 100
    yield (function () {return 200})()
    return 300
}

var h = Hello()
console.log(typeof h)  // object

console.log(h.next())  // { value: 100, done: false }
console.log(h.next())  // { value: 200, done: false }
console.log(h.next())  // { value: 300, done: true }
console.log(h.next())  // { value: undefined, done: true }

yield

The yield keyword causes the generator function to pause, and the value of the expression following the yield keyword is returned to the caller of the generator. It can be thought of as a Generator-Based version of the return keyword.

function* countAppleSales () {
  var saleList = [3, 7, 5];
  for (var i = 0; i < saleList.length; i++) {
    yield saleList[i];
  }
}
var appleStore = countAppleSales(); // Generator { }
console.log(appleStore.next()); // { value: 3, done: false }
console.log(appleStore.next()); // { value: 7, done: false }
console.log(appleStore.next()); // { value: 5, done: false }
console.log(appleStore.next()); // { value: undefined, done: true }

async/await

async function func() {
    try {
        let res = await asyncFunc()
    } catch (e) {
      //......
    }
}

The Promise object returned by the async function must wait until all the Promise objects of the await command inside are executed before the state changes occur.

The grammar of async function is not difficult, and it is difficult to deal with errors.

https://juejin.im/post/5a6547...
http://www.ruanyifeng.com/blo...
https://juejin.im/post/5a1681...
https://juejin.im/post/5ce75f...
https://developer.mozilla.org...
https://juejin.im/post/596e14...

Topics: Javascript Programming