ES6 has a new built-in class: Promise Promise/contract pattern, which effectively handles asynchronous programming (to demonstrate Promise)

Requirements: First get data from the server based on “/ API /1” interface; Then take some data as parameters, and get other data based on “/ API /2”; Finally, after the second data acquisition success, then based on “/ API /3” to obtain new data… If the first request succeeds, the second request succeeds, and the third request succeeds… “Serial AJAX”

  • The traditional implementation of asynchronous operations, and serial mode, are basically callback functions nested callback functions, implementation is very disgustingThe callback hellThe problem
$.ajax({
    url: '/api/1.json'.dataType: 'json'.success(result) {
        console.log('First request ->', result)
        
        // Ajax serial: the next request can be sent only after the first request succeeds
        $.ajax({
            url: '/api/2.json'.dataType: 'json'.success(result) {
                console.log('Second request ->', result)
                
                $.ajax({
                    url: '/api/3.json'.dataType: 'json'.success(result) {
                        console.log('Third request', result)
                        console.log('ok')}})}})Copy the code
  • At this time we need an excellent code management mode, can effectively manage the different programming code, through the idea of code management, so that the code development is more convenient, maintenance is also very convenient, readability is also stronger… => JS design patternThe Promise design pattern governs asynchronous programming
const api1 = () = > {
    return new Promise(resolve= > {
        $.ajax({
            url: '/api/1.json'.dataType: 'json'.success(result) {
                resolve(result)
            }
        })
    })
}

const api2 = () = > {
    return new Promise(resolve= > {
        $.ajax({
            url: '/api/2.json'.dataType: 'json'.success(result) {
                resolve(result)
            }
        })
    })
}

const api3 = () = > {
    return new Promise(resolve= > {
        $.ajax({
            url: '/api/3.json'.dataType: 'json'.success(result) {
                resolve(result)
            }
        })
    })
}

// The first option
api1().then(result= > {
    console.log('First request ->', result)
    // The state and result of the returned Promise instance are the state and result of.then
    return api2()
}).then(result= > {
    console.log('Second request ->', result)
    return api3()
}).then(result= > {
    console.log('Third request ->', result)
    console.log('OK')})// The second option
(async function() {
    let result = await api1()
    console.log('First request ->', result)
    
    result = await api2()
    console.log('Second request ->', result)
    
    result = await api3()
    console.log('Third request ->', result)
})()
Copy the code

1. Promise basic grammar

// Uncaught TypeError: Promise resolver undefined is not a function [executor]
// To call new, you must pass in a function
let p1 = new Promise(a)/ / complains

let p2 = new Promise(function() {
    console.log(1)})console.log(2)
Copy the code
  • The exexutor function passed is immediately executed when a new Promise is made

  • Exector is generally used to manage an asynchronous operation (it is possible not to write asynchronous)

    • The executor function is passed two arguments: resolve, reject and both are functions
  • Create an instance of the Promise class, P1

    • [[PromiseState]] state of promise

      • Pending State

      • This is very regrettable/resolved.

      • My rejected!

    • [[PromiseResult]] value promise

      • The default value is undefined, which generally stores the result of success or the cause of failure
    • Prototype: then/catch/finally

let p1 = new Promise(function(resolve, reject) {
    // Execute resolve to control the instance's state to succeed, passing the value as a result of success
        // + [[PromiseState]]: 'fulfilled'
        // + [[PromiseResult]]: 100
    // Execute reject to control the instance state to fail
        // + [[PromiseState]]: 'rejected'
        // + [[PromiseResult]]: 0
    // If the executor code executes incorrectly, the instance state changes to a failed state, and [[PromiseResult]] is the cause of the error
    // But once the state changes from pending to pity or Rejected, the state cannot be changed again
    resolve(100)
    reject(0)})console.log(1)
Copy the code
// How does Promise manage asynchronous programming
    // + new Promise creates a Promise instance that manages a set of asynchronous code in the executor function
    Resolve /reject controls the state and delivery of the Promise instance when the asynchronous operation succeeds or fails
    // + Depending on the state and result, you can control which of the two methods based on the.then injection is executed

let p1 = new Promise((resolve, reject) = > {
    // Execute executor immediately after the new Promise, and manage an asynchronous programming code in the executor function "the state is pending"; When the asynchronous operation reaches the specified time and starts to execute (understood as the asynchronous operation succeeds), we can perform resolve to change the promise state to depressing
    setTimeout(() = > {
        resolve('OK')},1000)
})

p1.then(result= > {
    // The first function will be executed, result -> [[PromiseResult]]
    console.log('success - >', result)
}, reason= > {
    [[PromiseResult]] [PromiseResult] [PromiseResult] [PromiseResult] [PromiseResult]
    console.log('failure - >', reason)
})
Copy the code
let p1 = new Promise((resolve, reject) = > {
    console.log(1) / / 1
    // Change the state and value, and inform the method based on THEN injection to execute "problem:.then has not been executed, method has not been injected, do not know who should be notified to execute"
    // Save the "action performed by the notification method" and "put it on the waiting task queue" -> The operation itself is asynchronous
    console.log(2) / / 2
})
p1.then(result= > {
    console.log('success - >', result) // Finally output
}, reason= > {
    console.log('failure - >', reason)
})
console.log(3) / / 3
Copy the code

2. Async await “ES7 new”

  • Async: decorates a function that returns a promise instance by default: “The function executes an error, the instance state is failure, and the result is the reason for the error; otherwise, the instance state is success, and the result is the value after return.”

  • 11. Await: generally used in conjunction with await, “to use await in a function must be based on async modification”, itself an asynchronous microtask: Store all the code to be executed under ‘await’ in the current context in an asynchronous microtask. After the promise instance behind ‘await’ becomes successful, execute the following code (i.e., the asynchronous microtask).

Grammar (await 'promise'Instance) : If the setting is not promise instance + normal valueawait 10 -> await Promise.resolve(10+ function executionawaitXXX () -> First execute the XXX function immediately, receiving its return value ->awaitThe return valuefunction computed() {
        console.log(1)
        return new Promise(resolve= > {
            setTimeout(() = > {
                resolve(2)},1000)})}console.log(3)
    async function fn() {
        console.log(4)
        let result = await computed()
        console.log(result)
        console.log(5)
    }
    fn()
    console.log(6)
Copy the code
The console throws an exception message that "does not affect subsequent code execution" + promise.catch(reason= > {})
    + awaitNeed to be based ontry catchDo exception catchingasync function fn() {
        try {
            let result = await Promise.reject(100)
            console.log(result)
        } catch(err) {
            console.log(err)
        }
    }
    fn()
Copy the code