Do we need Promise?

Look at the code below

$.ajax(url1, function(data1){
    // do something...
    $.ajax(url2, function(data2){
        // do something...
        $.ajax(url3, function(data3){
            // do something...
            done(data3); // Return data})}); });Copy the code
  • Easy to create when there are no asynchronous objectsCallback hellThe problem is that layers of nested code are extremely inconvenient to maintain and even harder to read
  • Asynchronous objects have been around since the days of Jquery$.DeferredLike the ones we use$.ajaxIt is code modified by an asynchronous object using an asynchronous object

Asynchronously parallel requests and processes them after the results are all returned

$.when($.ajax({
    url: 'https://www.easy-mock.com/mock/5937664f91470c0ac1073a73/example/test'
}), $.ajax({
    url: 'https://www.easy-mock.com/mock/5937664f91470c0ac1073a73/example/test'
})).done((p1, p2) = > {
    console.log(p1, p2)
})
Copy the code
let b = $.Deferred()
function a(dtd) {
    setTimeout(function () {
        console.log(1234)
        dtd.resolve('b is done')}, 400)return dtd

}


$.when(a(b)).done(res => {
    console.log(res)
})

Copy the code

It looks like an asynchronous object is actually a very convenient thing to use because it allows you to do some asynchronous code that you can write synchronously.

What is Promise?

Promise implementation specification Promise A+

  • Is a new feature of ES6 that has been included in the official specification of ES6
  • Promise objects can be thought of as asynchronous operations that are performed once, and they can be used to organize code in a chain of calls. Make the code more intuitive. That is, with the Promise object, asynchronous operations can be expressed as a flow of synchronous operations, eliminating layers of nested callback functions
  • Fix callback hell
  • Easy to maintain
  • Resolve synchronization asynchronously by returning results in order
  • The chain-call (JQ implementation relies on returning this) Promise cannot return this Promise. The chain-call dependency implementation returns a new Promise
  • If either a successful or a failed callback in a THEN returns a value, success in the next THEN returns a failure in the next THEN
  • If the first promise returns a normal value, it goes straight to the next THEN successful callback. If the first promise returns a promise, the result of the returned promise execution needs to be passed to the next THEN
  • resolvePromise
  • Determine if x is a promise. If x is an object and x’s then method is a function, we assume it is a promise
  • Promise values pass through empty then directly
  • The Promise specification requires that all onFufiled and onRejected be executed asynchronously
This is a big pity, which is a pity. Graph LR pendding -->Rejected --> this is a big pityCopy the code

Basic usage

Much like $.Deffered, it relies on returning an asynchronous object to solve callback hell

function test() {
    return new Promise((res, rej) = > {
        setTimeout(function () {
            console.log('Delayed execution')
            res('done')},2000)
    })
}
test().then(function (res) {
    console.log(res)
})

Copy the code

Make a simple Promise

From the code above we can see that a Promise has several characteristics

  • The argument is a function that contains two methods: resolve and reject
  • The returned instance contains then methods and the call timing of the THEN method is related to the execution of resolve and Reject
  • The return parameters of resolve and reject are passed directly to the THEN method

Initialize a Promise

function Promise(executor) {
    / / executor actuators
    this.status = 'pending'
    this.reason = null
    this.data = null

    function resolve() {}function reject() {

    }
    executor(resolve, reject)
}
Promise.prototype.then = function (res, rej) {}Copy the code

Added handling of incoming data when calling resolve and Reject

function Promise(executor) {
    / / executor actuators
    this.status = 'pending'
    this.reason = null
    this.data = null
    const _this = this;
    function resolve(data) {
        if (_this.status == 'pending') {
            _this.data = data
            _this.status = 'onFulfilled'}}function reject(e) {
        if (_this.status == 'pending') {
            _this.reason = e
            _this.status = 'rejected'
        }
    }
    executor(resolve, reject)
}
Promise.prototype.then = function (res, rej) {}Copy the code

The Promise state is modified at execution time and the timing of the call to the THEN function is handled

function Promise(executor) {
    / / executor actuators
    this.status = 'pending'
    this.reason = null
    this.data = null
    const _this = this;
    function resolve(data) {
        if (_this.status == 'pending') {
            _this.data = data
            _this.status = 'onFulfilled'}}function reject(e) {
        if (_this.status == 'pending') {
            _this.reason = e
            _this.status = 'rejected'
        }
    }
    executor(resolve, reject)
}
Promise.prototype.then = function (res, rej) {
    const _this =  this
    if(_this.status=='onFulfilled'){
        res(_this.data)
        return 
    }
    if(_this.status=='rejected'){
        res(_this.reason)
    }
}

Copy the code

Take a test walk

function test() {
    return new Promise(function (resolve, reject) {
        console.log('promise is running')
        resolve('2')
    })
}
test().then((res) = > {
    console.log(res)
}, (e) => {
    console.log(e, e)
})
Copy the code

OK synchronization code passed

The asynchronous invocation is then implemented

  • Added two new attributes onControllLedList onRejectedList to be invoked during asynchronous execution
function Promise(executor) {
    / / executor actuators
    this.status = 'pending'
    this.reason = null
    this.data = null
    this.onFulFilledList = []
    this.onRejectedList = []
    const _this = this;
    function resolve(data) {
        if (_this.status == 'pending') {
            _this.data = data
            _this.status = 'onFulfilled'}}function reject(e) {
        if (_this.status == 'pending') {
            _this.reason = e
            _this.status = 'rejected'
        }
    }
    executor(resolve, reject)
}
Promise.prototype.then = function (res, rej) {
    const _this = this
    if (_this.status == 'onFulfilled') {
        res(_this.data)
        return
    }
    if (_this.status == 'rejected') {
        rej(_this.reason)
    }
}

Copy the code

The success and failure functions of asynchronous calls are stored in queues to facilitate calls and the callback queue methods are directly executed when called

function Promise(executor) {
    / / executor actuators
    this.status = 'pending'
    this.reason = null
    this.data = null
    this.onFulFilledList = []
    this.onRejectedList = []
    const _this = this;
    function resolve(data) {
        if (_this.status == 'pending') {
            _this.data = data
            _this.status = 'onFulfilled'
            _this.onFulFilledList.forEach(element= >{ element(_this.data) }); }}function reject(e) {
        if (_this.status == 'pending') {
            _this.reason = e
            _this.status = 'rejected'
            _this.onRejectedList.forEach(element= > {
                element(_this.reason)
            });
        }
    }
    executor(resolve, reject)
}
Promise.prototype.then = function (res, rej) {
    const _this = this
    if (_this.status == 'onFulfilled') {
        res(_this.data)
        return
    }
    if (_this.status == 'rejected') {
        rej(_this.reason)
    }
    if (_this.status == "pending") {
        _this.onFulFilledList.push(res)
        _this.onRejectedList.push(rej)
    }
}
Copy the code

The test code


function test() {
    return new Promise((res, rej) = > {
        setTimeout(function () {
            console.time('promise')
            console.log(123)
            res('4')},2000)
    })
}
test().then((
    params
) => {
    console.log(params)
    console.timeEnd('a')})Copy the code

This implements the simplest asynchronous invocation of promises

The above content gives you a basic approach to ES6 Promise, hope to help you.