Promise, async, await knowledge points

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

Insert image description here
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 --> fulfilledcalledresolve(data)
  • from pending --> rejectedcalledreject(reason)

3. Follow-up processing :

  • fulfilledThe subsequent processing of is calledonFulfilled
  • rejectedThe subsequent processing of is calledonRejected

Insert image description here

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

Insert image description here
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 pendingin setTimeoutorder to obtain the final state.
As for setTimeoutwhy it can be obtained, refer to the event loop mechanism

Example 1, promise1it is in fulfilledstatus, 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 promise1is in rejectedstatus, 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, catchthe 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 Promiseobjects

static method effect
Promise.resolve() Tasks that directly return fulfilledstatus
Promise.reject() Tasks that directly return rejectedstatus
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:
Insert image description here

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
Insert image description here

4. async and await

async

1. asyncThe 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 asyncthe modified function explicitly returns a Promise object, the function is equivalent to not being asyncmodified.

async function fun() {
    
    
  return new Promise((resolve) => {
    
    
    resolve(1);
  });
}

await

1. awaitUsed to wait for a Promise object to be resolved and obtain the resolved result. If the result is in rejectedstatus, an exception will be thrown, which can be try...catchcaptured.

async function fun() {
    
    
  try {
    
    
    await Promise.reject(1);
  } catch (error) {
    
    
    console.log('error:' + error);
  }
}
fun() // error:1

2. Because awaitit needs to be placed in an asynchronous function, you can use an immediate execution function.

(async ()=> {
    
    
  await delay(1000)
  console.log('等待1s后执行后续操作');
})()

3. When awaitthe value of the expression after is not a Promise, awaitthe value will be converted into fulfilleda Promise of the state, and then the result will be returned.

await 1 //相当于 await Promise.resolve(1)

5. Interview questions

Interview questions


that's all.

Guess you like

Origin blog.csdn.net/qq_40147756/article/details/132711878
Recommended