async/await 和 promise 的用法

async/await 和 promise 的用法

 

参考:https://www.jianshu.com/p/ffa5cbe9ab29

promise

Promise构造函数的参数是一个函数,函数里面的代码是异步的,即Promise里面的操作,和Promise()外面的操作时异步"同时"进行的。Promise中的函数的第一个参数是回调函数,resolve用来触发then里面的代码,第二个参数是回调函数,reject用来触发catch中的代码,throw new Error();也可以触发catch,

resolve和reject是两个回调函数,调用resolve会触发then,reject会触发catch

<script>
new Promise((resolve, reject) =>{
    setTimeout(() =>{
        //成功的时候调用resolve
        resolve('成功data')
        //失败的时候调用reject
        reject('error message')
    }, 1000)
}).then((data) =>{
    //处理成功后的逻辑
    console.log(data);//这个data 是接收的resolve参数--
}).catch((err) =>{
    console.log(err);
})
</script> 

async/await ”vs“ promise

写法:

Promise主要用then函数的链式调用,一直点点点,是一种从左向右的横向写法。 async/await从上到下,顺序执行,就像写同步代码一样。这更符合人编写代码的习惯

参数数量

Promise的then函数只能传递一个参数,虽然可以通过包装成对象,但是这会导致传递冗余信息,频繁的解析又重新组合参数,比较麻烦。 async/await没有这个限制,就当做普通的局部变量来处理好了,用let或者const定义的块级变量,想怎么用就怎么用,想定义几个就定义几个,完全没有限制,也没有冗余的工作。

机制

Promise是根据函数式编程的范式,对异步过程进行了一层封装。 async/await是基于协程的机制,是真正的“保存上下文,控制权切换 ... ... 控制权恢复,取回上下文”这种机制,是对异步过程更精确的一种描述。

async/await

async/await是基于Promise的,是进一步的一种优化。不过再写代码的时候,Promise本身的API出现得很少,很接近同步代码的写法。

async只是表明里面可能有异步过程,里面可以有await关键字,如果没有async函数本身会马上返回,不会阻塞当前线程。它的函数的返回值是一个Promise对象。

return new Promise();则直接处理promise对象

return data;则相当于Promise.resolve(data);还是一个Promise对象

两者都需要用用.then(data => { })函数处理。

await的是resolve(data)消息,并把数据data返回。比如,下面代码中,当Promise对象由Pending变为Resolved的时候,变量a就等于data;然后再顺序执行下面的语句`console.log(a);

const a = await new Promise((resolve, reject) => {
    // async process ...
    return resolve(data);
});
console.log(a);

await等待的虽然是promise对象,但不必写.then(..),直接可以得到返回值。

通过await标记的方法,只有该方法执行完成之后才能往后执行

async function asyncFunction() {
    console.time('asyncFunction total executing:');
    const sleep1 = await sleep(2000);
    console.log('sleep1: ' + sleep1);
    const [sleep2, sleep3, sleep4]= await Promise.all([sleep(2000), sleep(1000), sleep(1500)]);
    console.log('sleep2: ' + sleep2);
    console.log('sleep3: ' + sleep3);
    console.log('sleep4: ' + sleep4);
    const sleepRace = await Promise.race([sleep(3000), sleep(1000), sleep(1000)]);
    console.log('sleep race: ' + sleepRace);
    console.timeEnd('asyncFunction total executing:');
    return 'asyncFunction done.'  // 这个可以不返回,这里只是做个标记,为了显示流程
}
  • sleep1: sleep for 2000 ms这是第一个await之后的第一个异步过程,后面的代码,不论是同步和异步,都在等他执行完毕。
  • sleep2 ~ sleep4这是第二个await之后的Promise.all()异步过程。这是“比慢模式”,三个sleep都完成后,再运行下面的代码s,耗时最长的是2000ms

  • sleep race: sleep for 1000 ms这是第三个await之后的Promise.race()异步过程。这是“比快模式”,耗时最短sleep都完成后,就运行下面的代码。耗时最短的是1000ms

  • asyncFunction total executing:: 5006.276123046875ms这是最后的统计总共运行时间代码。三个await之后的异步过程之和

异常捕获

对于异常的捕获,除了传统的try/catch

async getData() {
  try {
    this.formInfos = await getFormInfos();
  } catch (e) {
    Toast(`数据获取失败,请稍后重试`)
  }
}

也可以通过.catch去捕获异常

let books = await bookModel.fetchAll()
  .catch((error) => { console.log(error); });

结合之后使用

const responseJson = await Promise.race([
  fetch(url, requestConfig),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
])
.then((resPromise) => {
  let resultPromise = resPromise.json()
  return resultPromise
}).then((result) => {
  return result
}).catch((e)=>{
  throw new Error("网络出现问题~")
})

if (responseJson['success']) {
  return responseJson['obj']
} else {
  throw new Error(responseJson['msg'])
}

注意:

  • await 只能放在async函数内部使用,不能放在普通函数里面,否则会报错。

  • 后面放Promise对象,在Pending状态时,相应的协程会交出控制权,进入等待状态。这个是本质。

  • await后面也可以跟同步代码,不过系统会自动转化成一个Promise对象。 比如 const a = await 'hello world'; 其实就相当于 const a = await Promise.resolve('hello world');

  • await只关心异步过程成功的消息resolve(data),拿到相应的数据data。至于失败消息reject(error),不关心(可以放在一个try...catch结构中统一处理)

Promise

promise代表非阻塞异步执行的抽象,所谓的非阻塞异步执行就是,promise执行的时候,其他程序可以继续往下执行,不必像await一样,需要等待。

console.log('Starting Execution');

const promise = rp('http://example.com/');
promise.then(result => console.log(result));

console.log("Can't know if promise has finished yet...");

正确的使用方式

// 错误示范
async getBooksAndAuthor(authorId) {
  const books = await bookModel.fetchAll();
  const author = await authorModel.fetch(authorId);
  return {
    author,
    books: books.filter(book => book.authorId === authorId),
  };
}
// 这里await之后就会阻塞,执行完一个执行下一个

// 正确姿势
async getBooksAndAuthor(authorId) {
  const bookPromise = bookModel.fetchAll();
  const authorPromise = authorModel.fetch(authorId);
  const book = await bookPromise;
  const author = await authorPromise;
  return {
    author,
    books: books.filter(book => book.authorId === authorId),
  };
}
// promise会异步执行,的带结果之后执行await

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值