Detailed use of Promise in JavaScript

 Part 01 - Promise Overview

Promise A Better Unified Asynchronous Programming Scheme

Traditional asynchronous programming, such as ajax, is a series of executions following a request through a callback function.

However, if the complex asynchronous process is completed directly using the traditional callback method, a large number of callback functions can not be avoided.

This makes it easy to call back to Hell, resulting in Code Carton

Callback to Hell

get('url',function(){
    get2('url2',function(){
        get3('url3',function(){
                
            })
        })
    })

Finally, in order to solve the problem of callback Hell, the CommonJS community proposed a Promise scheme, which was eventually adopted as the standard specification in ES5.

What is Promise?

Promise is essentially an object that describes whether an asynchronous task will ultimately succeed or fail.

Part 02 - Promise Basic Usage

const promise = new Promise(function(resolve, reject) {
    // A callback function is used internally to indicate the execution of a promise,

    // Commitment to Success
    resolve('resolve200')

    // Commitment Execution Failure Create a new Failure Object
    reject(new Error('reject500'))
})

promise.then(function(value) {
    // Parameter 1 resolve function, used to execute successful results
    console.log(value, 'then');
}, function(err) {
    // Parameter 2 reject function, used to execute the failed result
    console.log(err, 'error');
})

Part03 - Promise use case

Encapsulating cases of ajax requests with promise

const ajax = function(url) {
    // Encapsulates an ajax function and returns promise as a function
    return new Promise(function(resolve, reject) {
        // Create http object
        var xhr = XMLHttpRequest()
        // Prepare to send request type and address
        xhr.open('GET', url)
        // The new h5 syntax fixes the received array to json format
        xhr.responseType = 'json'
        xhr.onload = function(res) {
            if (this.status === 200) {
                resolve(res)
            } else {
                reject(new Error(this.statusText))
            }
        }
        xhr.send()
    })
}


ajax('url address').then(function(value) {
    console.log(value);
}, function(err) {
    console.log(err);
})

Part04 - Chain call to Promise

The essence of Promise is to use callback functions to define what tasks to perform after an asynchronous task

Promise divides callback functions into two forms

  •  Callback after onFulfilled's success
  • Callback after onRejected failure
  • ajax(url)
        .then(function onFulfilled(res) {
            console.log(res);
        }, function onRejected(err) {
            console.log(err);
        })

Each then method returns a completely new Promise object with the goal of forming a new chain that ends with the Promise object.

ajax('url address').then(function(value) {
        console.log(value);
    }) // => Promise
    .then(function(value) {
        console.log(111);
    }) // => Promise
    .then(function(value) {
        console.log(222);
    }) // => Promise
    .then(function(value) {
        console.log(333);
    }) // => Promise
    .then(function(value) {
        console.log(444);
    }) // => Promise
    .then(function(value) {
        console.log(555);
    }) // => Promise
    .then(function(value) {
        console.log(666);
    })

After each chain call, then is actually executed after a callback from the Promise returned by the last one

So the return here is the synchronization type  Execute in sequence

ajax('url address').then(function(value) {
    console.log(value);

    return ajax('url address').then(function(value) {

        console.log(111);

    })
})

The return value of the callback function in the previous then method will be used as the parameter of the subsequent then method callback

If Promise is returned in the callback.Then the callback of the subsequent then method will wait for his end 

Chained calls can avoid multiple nested callbacks and ensure flattening of asynchronous requests.

Part05 - Promise exception handling

When Promise has no normal request, the onRejected function is executed

Or if an exception occurs in the resolve function, or if we manually throw one after the other, the onRejected function will also execute

We can register onRejected callbacks using the catch method of the Promise instance

ajax('url address').then(function(value) {
    console.log(value);
}).catch(function(err) {
    console.log(err);
})

unhandledrejection event

Can throw exceptions that are not caught in the browser

window.addEventListener('unhandledrejection', event => {
    const { reason, promise } = event
    console.log(reason, promise);
    // The reason=> Promsie failed, typically an error object
    // Promise =>Prose object with exception

    event.preventDefault()
}, false)

Part06 - Parallel execution of Promise

When you encounter multiple asynchronous tasks that can be executed simultaneously, you need to use Promise.all.

Promise.all()

Parameter: Array 

Inside the array is every request

Return value: promise object in array form

var promise = Promise.all([
    ajax(url1),
    ajax(url2)
])

promise.then(function(res) {
    console.log(res);
})

const p1 = async () => {}
const p2 = async () => {}
const p3 = async () => {}

const [result1, result2, result3] = await Promise.all([p1, p2, p3])

console.log(result1)
console.log(result2)
console.log(result3)

ajax('/api/users.json')
ajax('/api/posts.json')

ajax('/api/urls.json')
  .then(value => {
    const urls = Object.values(value)
    const tasks = urls.map(url => ajax(url))
    return Promise.all(tasks)
  })
  .then(values => {
    console.log(values)
  })

A Promise object will not be returned until all requests have been completed

If one of the requests fails, a failed object is returned.

 Promise.all() waits for all tasks to end

Promise.race() returns promise when the first task is completed

Part07 - Execution order of Promise

Even if promise does not have any asynchronous calls, it will still be suspended for asynchronous waiting

Tasks in the callback queue are called macro tasks

Additional requirements may be temporarily added to the execution of macro tasks for which you can choose to queue as a new macro task.

It can also be used as a [Micro Task] for the current task and executed immediately after the end of the current task.

The callback for promise is executed as a microtask.Executes at the end of this round of calls

Tags: Javascript Front-end ECMAScript Ajax

Posted on Sun, 05 Sep 2021 12:17:33 -0400 by plaztic