热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Promise、Generator和async踩坑记

目录1、Promise两种容易混淆的用法2、try-catch能不能抛出promise的异常?3、forEach中使用async的踩坑ES6异步处理之Promise对


目录

    • 1、Promise 两种容易混淆的用法
    • 2、try-catch 能不能抛出 promise 的异常?
    • 3、forEach 中使用 async 的踩坑



ES6 异步处理之 Promise 对象、Generator 函数 与 async 函数基础详解


1、Promise 两种容易混淆的用法


  • 在有回调函数的方法中

import request from 'request';const getThirdData = async(url, requestData) => {return new Promise((resolve, reject) => {request.post({url,method: "POST",json: false,headers: {"content-type": "application/json",},body: JSON.stringify(requestData)}, (error, response, body) => {// 回调函数error ? reject(error) : resolve(body);})})
}

  • 在没有回调函数的方法中

export const getApiListByType = (projectName) => {return new Promise((resolve, reject) => {fetch( url, {method: 'GET',mode: 'cors',credentials: 'include'}).then(res => resolve(res.json())).catch(err => reject(err))})
}



2、try-catch 能不能抛出 promise 的异常?

try-catch 主要用于捕获异常,注意,这里的异常,是指同步函数的异常,如果 try 里面的异步方法出现了异常,此时catch 是无法捕获到异常的,原因是因为:当异步函数抛出异常时,对于宏任务而言,执行函数时已经将该函数推入栈,此时并不在 try-catch 所在的栈,所以 try-catch 并不能捕获到错误。对于微任务而言,比如 promise,promise 的构造函数的异常只能被自带的 reject 也就是.catch 函数捕获到。

下面举两个例子说明:

// 异步,宏任务
try {setTimeout(function() {console.log(b);}, 0);
} catch (error) {console.log(error); // 这里是不会执行的
}
console.log('out try catch');

// 异步,微任务
try {new Promise(() => {throw new Error('new promise throw error');});
} catch (error) {console.log(error);
}

解决方案:


  • 同步任务:try…catch 就够了。
  • 异步任务:try…catch 结合 promise 的 catch() 方法一起使用。


3、forEach 中使用 async 的踩坑

错误再现:

const updateDataById = ctx => {const { list, id } = ctx.query;let result = null;try {result = list.forEach(async type => {await this.update({ id });})} catch (error) {result = {'error': error};}ctx.body = result;
}

解决方案:Promise.all() + map() 代替 forEach()

const updateDataById = async(ctx) => {const { list, id } = ctx.query;let result = null;try {await Promise.all(list.map(async type => {return await this.update({ id });})).then(data => result = data}).catch(error => result = error)} catch (error) {result = {'error': error};}ctx.body = result;
}

为什么这样改就可以了呢?
forEach与async/await使用踩坑
理解和使用Promise.all和Promise.race





参考文档:
try-catch 能抛出 promise 的异常吗
forEach与async/await使用踩坑


推荐阅读
author-avatar
拍友2502904975
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有