Promise && async /await

70 阅读5分钟

Promise 和 async/await--- 个人笔记

Promise是什么

Promise对象用于表示一个异步操作的最终完成(或失败)及其结果值。

promise实例被创建出来时不一定已经知道值是多少,是可以获取异步操作最终的成功返回值或者失败的原因。 (异步方法不会立即返回最终的值,用一个promise来接收,可以在未来某个时刻获得返回值的时候使用)

Promise必定处于以下三种状态之一: pending:初始状态 resolved:成功 rejected:失败

Promise.prototype.then 和 Promise.prototype.catch 方法返回的还是一个promise。 因为可以被链式调用。

Promise的链式调用

.then()方法需要俩参数: 第一个参数是成功状态的回调函数,第二个参数是失败状态的回调函数.且.then()方法还会返回一个新生成的promise对象。

p.then(onFulfilled[, onRejected]);

p.then(value => {
  // fulfillment
}, reason => {
  // rejection
});

var p1 = new Promise((resolve, reject) => {
  resolve('成功!');
  // or
  // reject(new Error("出错了!"));
});

p1.then(value => {
  console.log(value); // 成功!
}, reason => {
  console.error(reason); // 出错了!
});


链式调用
const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('foo');
  }, 300);
});

myPromise
  .then(handleResolvedA, handleRejectedA)
  .then(handleResolvedB, handleRejectedB)
  .then(handleResolvedC, handleRejectedC);

在最后一个链式调用时用catch语句进行错误处理

myPromise
  .then(handleResolvedA)
  .then(handleResolvedB)
  .then(handleResolvedC)
  .catch(handleRejectedAny);


箭头函数
myPromise
  .then(value => { return value + ' and bar'; })
  .then(value => { return value + ' and bar again'; })
  .then(value => { return value + ' and again'; })
  .then(value => { return value + ' and again'; })
  .then(value => { console.log(value) })
  .catch(err => { console.log(err) });

Promise构造函数 静态、实例方法

Promise()

静态方法

Promise.all(iterable) : 等到所有的 promise 对象都成功或有任意一个 promise 失败时返回一个新的 promise 对象, 如果所有的 promise 都成功了,它会把一个包含 iterable 里所有 promise 返回值的数组作为成功回调的返回值。顺序跟 iterable 的顺序保持一致。 只要任何一个输入的 promise 的 reject 回调执行或者输入不合法的 promise 就会立即抛出错误,并且 reject 的是第一个抛出的错误信息。

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
});
// expected output: Array [3, 42, "foo"]

Promise.allSettled(iterable) 返回一个在所有给定的 promise 都已经fulfilled或rejected后的 promise,并带有一个对象数组,每个对象表示对应的 promise 结果。

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];

Promise.allSettled(promises).
  then((results) => results.forEach((result) => console.log(result.status)));

// expected output:
// "fulfilled"
// "rejected"

Promise.any(iterable) 接收一个 promise 对象的集合,当其中的任意一个 promise 成功,就返回那个成功的 promise 的值。

Promise.race(iterable) 等到任意一个 promise 的状态变为settled 。 当 iterable 参数里的任意一个子 promise 成功或失败后,父 promise 马上也会用子 promise 的成功返回值或失败详情作为参数调用父 promise 绑定的相应处理函数,并返回该 promise 对象。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value);
  // Both resolve, but promise2 is faster
});
// expected output: "two"

Promise.reject(reason) 返回一个状态为已拒绝的 Promise 对象,并将给定的失败信息传递给对应的处理函数。

Promise.resolve(value) 返回一个解析过的 Promise 对象。

const promise1 = Promise.resolve(123);

promise1.then((value) => {
  console.log(value);
  // expected output: 123
});

实例方法 Promise.prototype.catch() 为 promise 添加一个被拒绝状态的回调函数,并返回一个新的 promise,若回调函数被调用,则兑现其返回值,否则兑现原来的 promise 兑现的值。

Promise.prototype.then() 为 promise 添加被兑现和被拒绝状态的回调函数,其以回调函数的返回值兑现 promise。 then() 方法返回一个 Promise。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。

const promise1 = new Promise((resolve, reject) => {
  resolve('Success!');
});
promise1.then((value) => {
  console.log(value);
  // expected output: "Success!"
});


p.then(onFulfilled[, onRejected]);
p.then(value => {
  // fulfillment
}, reason => {
  // rejection
});

Promise.prototype.finally() 为 promise 添加一个回调函数,并返回一个新的 promise。这个新的 promise 将在原 promise 被兑现时兑现。而传入的回调函数将在原 promise 被敲定(无论被兑现还是被拒绝)时被调用。

async await

async和await关键字可以用于以一种更简洁的方式写出 基于Promise的异步行为,从而不用链式去调用promise。

function resolveAfter2Seconds() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('resolved');
    }, 2000);
  });
}

async function asyncCall() {
  console.log('calling');
  const result = await resolveAfter2Seconds();
  console.log(result);
  // expected output: "resolved"
}

asyncCall();     //  calling
                 //resolved

语法

async function name(param0) {
  statements
}
async function name(param0, param1) {
  statements
}
async function name(param0, param1, /* … ,*/ paramN) {
  statements
}

参数
name
函数名称。

param 可选
要传递给函数的参数的名称。

statements 可选
包含函数主体的表达式。可以使用 await 机制。

返回值
一个 Promise,这个 promise 要么会通过一个由 async 函数返回的值被解决,要么会通过一个从 async 函数中抛出的(或其中没有被捕获到的)异常被拒绝。

async 函数可能包含 0 个或者多个 await 表达式。await 表达式会暂停整个 async 函数的执行进程并出让其控制权,只有当其等待的基于 promise 的异步操作被兑现或被拒绝之后才会恢复进程。promise 的解决值会被当作该 await 表达式的返回值。使用 async/await 关键字就可以在异步代码中使用普通的 try/catch 代码块。

async/await的目的为了简化使用基于 promise 的 API 时所需的语法。

async 函数一定会返回一个 promise 对象。如果一个 async 函数的返回值看起来不是 promise,那么它将会被隐式地包装在一个 promise 中。

async function foo() {
 return 1;
}

等价于:
function foo() {
 return Promise.resolve(1);
}

async 函数的函数体可以被看作是由 0 个或者多个 await 表达式分割开来的。从第一行代码直到(并包括)第一个 await 表达式(如果有的话)都是同步运行的。这样的话,一个不含 await 表达式的 async 函数是会同步运行的。然而,如果函数体内有一个 await 表达式,async 函数就一定会异步执行。

async function foo() {
  await 1;
}
等价于
function foo() {
  return Promise.resolve(1).then(() => undefined);
}

在 await 表达式之后的代码可以被认为是存在在链式调用的 then 回调中,多个 await 表达式都将加入链式调用的 then 回调中,返回值将作为最后一个 then 回调的返回值。

可以理解为: Promise是用来保存未来某个时间这个时间执行的结果 async await是Promise的简化写法 用await 可以不需要写链式调用