Promise

state

A Promise is always in one of three states:

  • pending: Initial state
  • fulfilled/resolved: Success
  • rejected: Indicates failure.

States have some properties:

  • It can only be modified by executing functions
  • External cannot read
  • External cannot be modified

Promise.prototype.then

Add the main method of the handler to the Promise instance. The two parameters received indicate that they will be called when the Promise/Resolved or Rejected state, respectively, and the two are mutually exclusive. Two arguments are optional, but must be of function type. Non-function types are ignored. A Promise instance can have any number of handlers (any number of THEN calls)

Promise.prototype.catch

Equivalent to the Promise. Prototype. Then (null, onRejected)

Promise.prototype.finally

No matter the state is regrettable /resolved or Rejected, it will be implemented, but the specific state cannot be known (it has nothing to do with the state). It is mainly used for cleaning

Execution order

Example 1

const p = new Promise(resolve= > {
    console.log('1. excute promise');
    setTimeout(() = > {
        console.log('3. before resolve')
        resolve();
        console.log('4. after resolve')},100);
})

p.then(() = > {
    console.log('5. execute resolve')
}).then(() = >{
    console.log('6. then2')
}).then(() = >{
    console.log('7. then3')
}).finally(() = >{
    console.log('8. finally')});console.log('2. sync then')

/**
result:
1. excute promise
2. sync then
3. before resolve
4. after resolve
5. execute resolve
6. then2
7. then3
8. finally
*/
Copy the code

Example 2

const p = new Promise(resolve= > {
    setTimeout(() = > {
        resolve();
    }, 100);
})

p.then(() = >{
    console.log('then1')
}).then(() = >{
    console.log('then2')
}).then(() = >{
    console.log('then3')
}).then(() = >{
    console.log('then4')
}).then(() = >{
    console.log('then5')});console.log('async then')

/**
result:
async then
then1
then2
then3
then4
then5
*/
Copy the code

Then1, then2, then3, then4, then5 in this example are executed synchronously

Chain calls

Chained calls to THEN are the most common use of promises, in that each executor returns a Promise instance and each subsequent THEN waits for the previous one to be executed, i.e. asynchronous serialization. To solve the asynchronous callback hell conundrum.

The ES6 specification does not support Promise termination and progress queries because it makes promises too complex.

Chain transfer value

const p = new Promise(resolve= > {
    setTimeout(() = > {
        resolve(100);
    }, 100);
})

p.then(value= > {
    console.log(value)
    return value + 1;
}).then(value= > {
    console.log(value)
    return new Promise(resolve= > {
        setTimeout(() = > {
            resolve(value + 1)},3000);
    });
}).then(value= > {
    console.log(value)
    return value + 1;
}).then(value= > {
    console.log(value)
    return value + 1;
}).then(value= > {
    console.log(value)
    return value + 1;
});

/** 100 101 102 Wait 3 seconds 103 104 */
Copy the code

If the executing function returns a Promise object, subsequent calls wait for that object to settle and then fire, passing a resolve value. If not, it is immediately triggered to pass the value back through the return statement

The impact of catch on the call chain

catchIn the last
const p = new Promise(resolve= > {
    setTimeout(() = > {
        resolve(100);
    }, 100);
})

p.then(value= > {
    console.log(value)
    return value + 1;
}).then(value= > {
    console.log(value)
    return new Promise((resolve, reject) = > {
        setTimeout(() = > {
            reject('fail')},3000);
    });
}).then(value= > {
    console.log(value)
    return value + 1;
}).then(value= > {
    console.log(value)
    return value + 1;
}).then(value= > {
    console.log(value)
    return value + 1;
}).catch(err= > {
    console.log('catch', err);
    return new Promise((resolve, reject) = > {
        setTimeout(() = > {
            resolve(400)},3000);
    });
});
/**
100
101
catch fail
*/
Copy the code

When catch is at the end of the call chain, reject subsequent then are not fired

catchIn the middle
const p = new Promise(resolve= > {
    setTimeout(() = > {
        resolve(100);
    }, 100);
})

p.then(value= > {
    console.log(value)
    return value + 1;
}).then(value= > {
    console.log(value)
    return new Promise((resolve, reject) = > {
        setTimeout(() = > {
            reject('fail')},3000);
    });
}).then(value= > {
    console.log(value)
    return value + 1;
}).catch(err= > {
    console.log('catch', err);
    return 500;
}).then(value= > {
    console.log(value)
    return value + 1;
}).then(value= > {
    console.log(value)
    return value + 1;
});
/**
100
101
catch fail
*/
Copy the code

A catch is in the middle of the call chain, and if it does not return a Promise object, subsequent then will not be fired

async & await

async

Grammar:

async function name([param[, param[, ... param]]]) {
   statements
}
Copy the code
  • Name: indicates the function name
  • Param: The name of the argument to be passed to the function
  • Statements: An expression containing the body of a function, which can be usedawaitmechanism
  • Return value: onePromisethePromiseOr it will pass through aasyncThe value returned by the function is resolved, either by a value fromasyncAn exception thrown (or not caught) by a function is rejected

The async keyword is used to declare asynchronous functions. It can be used on function declarations, function expressions, arrow functions, and methods:

async function foo() {}
let bar = async function () {}
let baz = async() = > {}class Person{
    async say(){}}Copy the code

If an asynchronous function returns a value using the return keyword, that value is wrapped as a Promise object: promise.resolve ()

async function test() {
    return 2;
}
test().then(value= > {
    console.log(value)
})
console.log(1)

/ * * 1 2 * /
Copy the code

If an exception is thrown in the body of a function, we can use a catch to handle it:

async function test() {
    const result = 100 / a;
    return result;
}
test().catch(value= > {
    console.log(value)
})
console.log(1)
/**
1
ReferenceError: a is not defined
*/
Copy the code

Some sources say that exceptions that reject promises are not caught by asynchronous functions, but they are supported in the latest versions of Chrome (95.0.4638.69), Microsoft Edge (95.0.1020.40), and Firefox (93.0) :

async function test() {
    return Promise.reject('error');
}
test().catch(value= > {
    console.log(value)
})
console.log(1)
/**
1
error
*/
Copy the code

await

Grammar:

[return value] = await expression;

  • Expression: a Promise object or any value to wait for
  • Return value: ReturnsPromiseObject processing result. If the waiting is notPromiseObject, returns the value itself

In usage, await can be used either alone or in expressions:

async function func(){
    console.log(await Promise.resolve('foo'))
}
func();
/**
foo
*/
Copy the code

Await can only be used at the top level within async functions and nesting is not supported

It is sometimes a good thing to ignore the order after focusing on the result with multiple await, because different specifications have different ways of processing await promises.