Asynchronous definition

The most intuitive way to understand asynchronous programming is to pause in the middle of task A, go to another task B, and then go back to the break point and continue task A.

Imagine a scenario

  • JS reads file a.txt and obtains data dataA=1;
  • Then read file b.txt and obtain data dataB=2;
  • Then read the file c.txt and get the data dataC=3;
  • The sum is equal to 6.

The old callback functions handled asynchronous operations

Function successCallback(result){cosnole.log(' success '+ result)} function failureCallback(error){console.log(' failure' + result)} function failureCallback(error){console.log(' failure '+ result error) } createAudioFileAsync(set,successCallback,failureCallback)Copy the code

promise

Definition: Promise is an ES6 solution that provides asynchronous programming by expressing asynchronous operations as a flow of synchronous operations, avoiding layers of nested callback functions.

Specific expressions:

  • Syntactically: Promise is a constructor
  • Functionally: The Promise object encapsulates an asynchronous operation and can retrieve its results

Promise process

What development pain points promise addresses

  • Color {red}{the output of the first function is the input of the second function} the output of the first function is the input of the second function
doSomething(function(result){ doSomethingElse(result,function(newResult){ doThirdThing(newResult,function(finalResult){ Console. log(' get data ')},failureCallback)},failureCallback)},failureCallback)Copy the code
  • Promises can support multiple concurrent requests, retrieving data from concurrent requests

  • Promise solves the readability problem of asynchronous nesting

doSomething().then(function(result){ return doSomethingElse(result) }) .then(function(newResult){ return DoThirdThing (newResult)}). Then (function(finalResult){console.log(' data ')}). Catch (failureCallBack)Copy the code
  • Promises are more flexible, with older callback functions that must be specified before an asynchronous task can be started. Promise: Starts the asynchronous task = “returns the Promise object =” binds the promise object to the callback function

How to use Promise

  • Create a Promise instance
  • After the Promise instance is generated, you can use the THEN method to specify the resolved and Rejected state callback functions, respectively
  • Use the try and catch methods of Promise to prevent exceptions
// Create a new Promise object const p = new Promise((resolve,reject) =>{setTimeout(() =>{const time = Date.now() if(time %2 == 0) {resolve(' reject ')}else{reject(' reject ')}},1000)}) Console. log(' success ')} reason =>{// receive failed reason data console.log(' failure ')})Copy the code

Promise features:

1. The status of an object is not affected by external conditions: Only the result of an asynchronous operation can modify the internal status of the object. Promise has three states. This is a big pity (失败), which is Pending(不 会) and Rejected (failed).

2. Once the status changes, it will not change again: Status change Pending =>Resolved or Pending => Rejected. The result data for success is usually called value, and the result data for failure is usually called Reason

Promise:

1: Once created, it is executed immediately and cannot be cancelled.

2: If the callback function is not set, errors thrown inside a Promise will not be reflected externally. You cannot use try catch to catch exceptions.

3: When in the Pending state, there is no way to know what stage of progress is currently in (just started or nearly completed).

4: Compared with async usage, the use of a lot of THEN is more complicated.

Make a Promise

A Promise is an object that generates a Promise instance, and the constructor takes a function as an argument. The Promise instance uses THEN to handle callbacks. Then can take two arguments, the first a callback after success and the second a callback if failure (optional).

1: the chain call to 2:Promise is executed immediately after creation. Chain calls are implemented using then and catch methods. Although there are two inputs to THEN, it is not recommended to implement the failed state inside THEN, because the code will be cumbersome if the call is made in chain form. The catch method can simplify the implementation. The unified method of throwing an exception is used to catch the catch method after the chain call. Avoid every then, implementing a reject callback.

Promise:

  • Promise.then

    • .then its own implementation result is a promise. This means that we can link any number of.then, and the result of the previous THEN callback will be passed as an argument to the next THEN callback.
  • Promise.all

    • Merge multiple Primise instances into one instance, and the callback will only be executed when all instances become Resolved or one of them becomes Rejected.
  • Promise.race()

    • Is to wrap multiple Promise instances into a new Promise instance, multiple instances of one instance state changes, the instance state changes, return the first changed instance state.
  • done()

    • The callback chain of a Promise object, whether ending in a then or catch method, may not be caught if the last method throws an error (because errors within a Promise do not bubble up globally). Therefore, we can provide a done method that is always at the end of the callback chain, guaranteed to throw any errors that might occur.
  • finally()

    • The finally method is used to specify actions that will be performed regardless of the final state of the Promise object. The biggest difference from the done method is that it takes as an argument a normal callback function that must be executed anyway. Instances can be used for loading in network requests

What determines the result state of the new promise returned by promise.then()

1) Simple expression: determined by the result of execution of the callback function specified by then().

2.

  • If an exception is thrown, the new promise changes to Rejected, and Reason is the exception thrown
  • If an arbitrary value is returned that is not a PROMISE, the new Promise becomes resolved and value is the returned value
  • If another new promise is returned, the result of that promise becomes the result of the new promise
new Promise((resolve,reject)=>{
    resolve(1)
}).then(
    value => {
    console.log('onResolved()',value) //  1
 },
 reason => {
  console.log('onRejected()',reason)
 }
).then(
 value =>{
  console.log('onResolved()',value) // undefined
 },
 reason => {
  console.log('onRejected()',reason)
 }
)
Copy the code

Conclusion: 1 undefined

Promise exception passthrough?

  • When using promise’s then chain invocation, the failed callback can be specified at the end
  • Any previous operations other than exceptions are passed to the last failed callback

Interrupt the chain of promise

  • When using a promise’s then chain call, it breaks in the middle, and no subsequent callback function is called
  • Solution: Return a Promise object in a pending state in the callback function

Async/await (to perform operations asynchronously in a synchronous manner)

Async — Define async function someName(){… })

  • Async precedes a function literal or function expression (normal, immediate, or arrow), and returns a Promise object when the modified function executes.

  • The return value in the function body is the argument to resolve.

  • The body of the reject function throws an error, which takes the error message as a reject argument.

async function test() { console.log("test"); return 20; Function test() {return new Promise((resolve, reject) => {console.log("test"); resolve(20); }); }Copy the code

Await – suspend execution of asynchronous functions (var result = await someAsyncCall();)

  • Await must be inside async function.

  • Await normally precedes the Promise object, so it precedes the execution of async functions, but ordinary functions that return a Promise can also do so.

  • Await takes the result of the object, which is the resolve or reject argument in then. If it is not a Promise object, the corresponding value is returned.

  • If an await object is not preceded by a Promise object, it will be wrapped in promise.resolve.

  • Execution of await will be forced to wait until the result is received, execution of subsequent code inside the function will be blocked, the function itself will not block the whole code

Return new Promise((resolve, reject) => {setTimeout(() => {resolve(30); }, 1000); })} const foo = async () => {const t = await fn(); console.log(t); console.log('next code'); } foo(); // result: // 30 // next codeCopy the code

Resolution:

When an async function encounters an await, it waits for the function following the await to complete and does not execute the following next code directly.

Async and await functions

  • Simplify the use of promises.
  • Make your asynchronous code look synchronous
  • Async and await are used to handle asynchrony. That is, you need to do it asynchronously, you need to return the result asynchronously, and then you need to continue with the result.
  • Async is short for ‘asynchronous’ and await can be thought of as short for async wait.
  • Async is used to declare that a function is asynchronous and await is used to wait for an asynchronous method to complete.

Exception handling

In promises, we know that exceptions are caught by catch. When async is used, exceptions are caught by try/catch.

Return new promise ((resolve, reject) => {setTimeout(() => {reject('some error ')); }, 1000); })} const foo = async () => {try {await fn(); } catch (e) { console.log(e); // some error } } foo();Copy the code

If there are more than one await function, only the first caught exception will be returned.

function fn1() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('some error fn1.');
        }, 1000);
    })
}
function fn2() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('some error fn2.');
        }, 1000);
    })
}

const foo = async () => {
    try {
        await fn1();
        await fn2();
    } catch (e) {
        console.log(e);  // some error fn1.
    }
}

foo();
Copy the code

For additional

If a promise gets an exception, it goes to the callback for the second argument to then, and if that argument doesn’t exist, it goes to the catch.

let p = new Promise((resolve, reject) => { throw new Error('some errors') // resolve() // reject() }); P.t hen (res = > {the console. The log (' 1111 ')}, res = > {the console. The log (' 2222 ')}). The catch (e = > {the console. The log (' 3333 ')}) / * * * the results as follows: * 2222 * /Copy the code

Chain operations can continue after a failed operation (i.e., a catch), even if one of the actions in the chain fails to help the new action continue.

new Promise((resolve, reject) => {
    console.log('Initial');
 
    resolve();
})
.then(() => {
    throw new Error('Something failed');
        
    console.log('Do this');
})
.catch(() => {
    console.log('Do that');
})
.then(() => {
    console.log('Do this whatever happened before');
})
Copy the code

Initial

Do that

Do this whatever happened before