异步方法顺序调用问题

前端应用中时常出现多个异步方法需要依次调用,且后一个异步方法的执行依赖于前一个异步方法的返回结果的情况,下面主要介绍一下这种情况的处理方法。

方法1:异步方法嵌套调用

此种方法逻辑简单,但代码较为繁琐。


方法2:使用async函数参考ES6 async函数

ES2017 标准引入了 async 函数,使得异步操作变得更加方便。

2.1 用法

在函数的前面加上async关键字,表明该函数内部有异步操作。该函数在执行的时候遇到await就会返回,再接着执行函数体后面的语句。

正常情况下,await命令后面是一个Promise 对象,返回该对象的结果;如果不是Promise对象,就直接返回对应的值。

async function getStockPriceByName(name) {
  const symbol = await getStockSymbol(name);
  const stockPrice = await getStockPrice(symbol);
  return stockPrice;
}

getStockPriceByName('goog').then(function (result) {
  console.log(result);
});

async函数返回一个 Promise 对象,可以使用then方法添加回调函数。函数内部的return语句的返回值,会成为then方法回调函数的参数。

如果async函数内部抛出错误,则会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。

注意: 任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。

async function f() {
  await Promise.reject('出错了');
}

f()
.then(v => console.log(v))
.catch(e => console.log(e))
// 出错了
async function f() {
  await Promise.reject('出错了');
  await Promise.resolve('hello world'); // 不会执行
}

2.2 错误处理

如果希望即使前一个异步操作失败,也不要中断后面的异步操作,可以使用下面两种方法:

  • 可以将第一个await语句放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。如果有多个await命令,可以统一放在try...catch结构中。
async function f() {
  try {
    await Promise.reject('出错了');
  } catch(e) {
  }
  return await Promise.resolve('hello world');
}

f().then(v => console.log(v))
// hello world
  • await后面的 Promise 对象再跟一个catch方法,处理前面可能出现的错误。
async function f() {
  await Promise.reject('出错了')
    .catch(e => console.log(e));
  return await Promise.resolve('hello world');
}

f()
.then(v => console.log(v))
// 出错了
// hello world

2.3 Promise 对象的状态变化

async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

注意: await命令只能用在async函数之中,如果用在普通函数,就会报错。


方法3:使用Rxjs操作符

3.1 使用zip操作符(参考RxJS-zip

使用zip方法将多个 Observable 组合以创建一个 Observable,该 Observable 的值是由所有输入 Observables 的值按顺序计算而来的。

如果最后一个参数是函数,这个函数被用来计算最终发出的值;否则,返回一个顺序包含所有输入值的数组。

使用时需要在文件中导入操作符:

import { zip } from 'rxjs';

zip(
    observable1,
    observable2,
).subscribe(([result1, result2]) => {
    // do something
});

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值