Table of contents
1. Promise A+ specification
1. All asynchronous scenarios should be regarded as an asynchronous task
Appears as an object in js - Promise object . That is, the task object.
2. Promise objects have 2 phases and 3 states
1. Task creation :
- Tasks always go from the pending stage to the resolved stage and cannot be reversed.
- Tasks always go from suspended state to completed or failed state and cannot be reversed.
- The task is in the pending state at the beginning. Once the task is completed or fails, the state cannot be changed .
const result = new Promise((resolve, reject) => {
resolve(1);
reject(2); // 无效
resolve(3); // 无效
console.log(123); // 正常执行
});
console.log(result); // Promise {<fulfilled>: 1}
2. Change status :
- from
pending --> fulfilled
calledresolve(data)
- from
pending --> rejected
calledreject(reason)
3. Follow-up processing :
fulfilled
The subsequent processing of is calledonFulfilled
rejected
The subsequent processing of is calledonRejected
2. Promise simple API
1. Create tasks
const pro = new Promise(() => {
console.log('会被立即执行的函数');
})
console.log(pro) // Promise { <pending> }
2. Change status
const pro = new Promise((resolve, reject) => {
console.log('会被立即执行的函数')
setTimeout(() => {
if (Math.random() < 0.5) {
resolve('成功') // 从 pending 状态 --> fulfilled 状态
} else {
reject('失败') // 从 pending 状态 --> rejected 状态
}
}, 1000);
})
3. Follow-up processing
pro.then(
// fulfilled 的回调函数
(data) => {
console.log(data)
},
// rejected 的回调函数
(reason) => {
console.log(reason)
}
)
Practical example: delay delay utility function
function delay(duration) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, duration);
});
}
await delay(3000)
3. Chain call
Use then()
the and catch()
functions for subsequent processing.
promise.then(
// fulfilled 的回调函数
(data) => {
console.log(data)
},
// rejected 的回调函数
(reason) => {
console.log(reason)
}
)
// 相当于
promise
.then(
// fulfilled 的回调函数
(data) => {
console.log(data);
}
)
.catch(
// rejected 的回调函数
(reason) => {
console.log(reason);
}
);
Common writing methods:
/*
* 任务成功后,执行处理1,失败则执行处理2
*/
promise.then(处理1).catch(处理2)
/*
* 任务成功后,依次执行处理1、处理2,若 promise 任务失败 或 处理1和2有错,都会执行处理3
*/
promise.then(处理1).then(处理2).catch(处理3)
characteristic:
3.1, then() must return a new Promise object (new task).
According to the equivalent writing above, catch()
a new Promise object (new task) will also be returned.
3.2. The status of the new task depends on the subsequent processing of the previous task.
- If there is no relevant subsequent processing, the status of the new task is the same as that of the previous task, and the data is the data of the previous task.
In other words, irrelevant subsequent processing functions will not be executed.
In the following example, because the initial state of Promise is
pending
insetTimeout
order to obtain the final state.
As forsetTimeout
why it can be obtained, refer to the event loop mechanism
Example 1, promise1
it is in fulfilled
status, but there is no then()
corresponding follow-up processing.
const promise1 = new Promise((resolve) => {
resolve(1);
});
const promise2 = promise1.catch(() => {
console.log("不会被打印");
});
setTimeout(() => {
console.log(promise2); // Promise {<fulfilled>: 1}
});
Example 2 promise1
is in rejected
status, but there is no catch()
corresponding follow-up processing.
const promise1 = new Promise((resolve, reject) => {
reject(1);
});
const promise2 = promise1.then(() => {
console.log("不会被打印");
});
setTimeout(() => {
console.log(promise2); // Promise {<rejected>: 1}
});
- If there is subsequent processing but has not yet been executed, the new task is suspended .
const promise1 = new Promise((resolve) => {
console.log(1);
setTimeout(() => {
resolve();
}, 1000);
});
const promise2 = promise1.then(() => {
console.log(2);
});
setTimeout(() => {
console.log(promise2);
});
// 1
// Promise {<pending>}
// 2
- If subsequent processing is executed, the status of the new task is determined based on the subsequent processing:
- The subsequent processing is executed without errors, the status of the new task is completed, and the data is the return value of the subsequent processing (no return, it is undefined)
- There is an error in the execution of subsequent processing, the status of the new task is failed, and the data is an exception object.
- What is returned after subsequent execution is a task object, and the status and data of the new task are consistent with the task object.
Example of case 1:
const promise1 = new Promise((resolve) => {
resolve();
});
const promise2 = promise1.then(() => {
return 123;
});
setTimeout(() => {
console.log(promise2); // Promise {<fulfilled>: 123}
});
const promise1 = new Promise((resolve, reject) => {
reject();
});
const promise2 = promise1.catch(() => {
return 123;
});
setTimeout(() => {
console.log(promise2); // Promise {<fulfilled>: 123}
});
Example of the second case, catch
the same principle applies.
const promise1 = new Promise((resolve) => {
resolve();
});
const promise2 = promise1.then(() => {
throw "一个错误";
});
setTimeout(() => {
console.log(promise2); // Promise {<rejected>: '一个错误'}
});
For example, the third case:
const promise1 = new Promise((resolve) => {
resolve();
});
const promise2 = promise1.then(() => {
// promise2 的状态取决于这个 Promise 对象的状态
return new Promise((resolve, reject) => {
resolve(1);
});
});
setTimeout(() => {
console.log(promise2); // Promise {<fulfilled>: 1}
});
an interview question
const result = new Promise((resolve) => {
resolve(1);
})
.then((res) => {
console.log(res); // 1
return new Error(2); // 注意,这不是报错,而是一个对象
})
// 不执行
.catch((err) => {
throw err;
})
// 对上一个 then 返回的 Promise 做了处理,但没有返回结果。
.then((res) => {
console.log(res);
});
setTimeout(() => {
console.log(result); // Promise {<fulfilled>: undefined}
});
3. Promise static method
Tasks are
Promise
objects
static method | effect |
---|---|
Promise.resolve() | Tasks that directly return fulfilled status |
Promise.reject() | Tasks that directly return rejected status |
Promise.all(task array) | Returns an array. If all tasks succeed, it will succeed if any one fails. |
Promise.any(task array) | Returns a task if any one succeeds or fails if all tasks fail, and returns an array. |
Promise.race(task array) | Returns a task. As long as one of the tasks enters the decided state, it is decided and the state is consistent with it. |
Promise.allSettled(task array) | Returns an array of tasks. If all tasks in the array are successful, the task will not fail. |
Mainly introducePromise.allSettled(任务数组)
1. When the task array becomes decided, the results of each task are returned.
Promise.allSettled([
Promise.resolve(1),
Promise.reject(2),
new Promise((resolve) => {
resolve(3)
})
]).then((values) => {
console.log(values);
});
result:
2. When there is a pending task in the task array, it will always be in the pending state.
Promise.allSettled([
Promise.resolve(1),
Promise.reject(2),
new Promise(() => {
})
]).then((values) => {
console.log(values); // then() 永远不被执行
});
Practical example: All request results need to be obtained. It does not matter if there are failed requests. In the end, all successful data can be obtained.
// 模拟请求
function getData(pageIndex) {
return new Promise((resolve, reject) => {
if (Math.random() < 0.4) {
reject("网络错误");
}
setTimeout(() => {
resolve(pageIndex);
}, Math.floor(Math.random() * 3000));
});
}
const arr = [];
for (let i = 0; i < 5; i++) {
arr.push(getData(i));
}
Promise.allSettled(arr).then((values) => {
console.log(values);
});
result
4. async and await
async
1. async
The keyword is used to modify the function. The function modified by it must return a Promise object.
async function fun() {
}
console.log(fun()) // Promise {<fulfilled>: undefined}
async function fun2() {
await 1
}
console.log(fun2()) // Promise {<pending>}。因为有异步代码
2. If an error is reported during the execution process, the task isrejected
async function fun() {
throw new Error(1);
}
console.log(fun()); // Promise {<rejected>: Error: 1
3. When async
the modified function explicitly returns a Promise object, the function is equivalent to not being async
modified.
async function fun() {
return new Promise((resolve) => {
resolve(1);
});
}
await
1. await
Used to wait for a Promise object to be resolved and obtain the resolved result. If the result is in rejected
status, an exception will be thrown, which can be try...catch
captured.
async function fun() {
try {
await Promise.reject(1);
} catch (error) {
console.log('error:' + error);
}
}
fun() // error:1
2. Because await
it needs to be placed in an asynchronous function, you can use an immediate execution function.
(async ()=> {
await delay(1000)
console.log('等待1s后执行后续操作');
})()
3. When await
the value of the expression after is not a Promise, await
the value will be converted into fulfilled
a Promise of the state, and then the result will be returned.
await 1 //相当于 await Promise.resolve(1)
5. Interview questions
that's all.