Promise是ES6提出的异步编程的新解决方案,旧方案是单纯的使用回调函数。从语法上看,Promise是一个构造函数,既然是构造函数就可以用来对象的实例化,接受一个函数(执行器函数)作为参数,从功能上看,promise对象用来封装一个异步操作,并可以获取其成功/失败的结果值。获取到结果值后,就可以在回调函数中,对结果值进行处理。
---- 异步操作有 ①fs 文件操作 ②数据库操作 ③Ajax ④定时器

一、promise.then返回结果几种情况

首先实例化一个promise对象。promise对象身上有then方法,可用来指定回调,对成功和失败的结果进行处理。它接受两个回调函数,一个是resolve成功的回调,一个是reject失败的回调。

const p = new Promise((resolve, reject) => {setTimeout(() => {resolve('成功的回调');// reject('失败的回调');}, 1000);
});
p.then(value => { }, reason => { });

需要记住的是p.then返回的也是一个promise对象,因此可以进行链式调用。这也是promise可以解决异步编程回调地狱的原因,

重点:then返回的promise对象p1的状态是由then内部回调函数的执行结果来决定的,不取决于p的状态,不取决于你调用的是p的成功或者失败的回调,也就是p1的状态只看回调函数的执行结果。

而回调函数的执行结果有几种情况。如下

1. 如果回调函数的返回结果是 非promise类型的 属性,则then方法返回的promise对象p1的状态为成功fulfilled,同时返回的结果就是promise对象p1成功的值11112222,如下图。需要注意的是,如果你不写return,我们知道函数内部如果不写return默认返回结果是undefined,又undefined也是非promise类型,所以p1状态还是成功fulfilled,返回的promise成功值为undefined。

const p1 = p.then(value => {        //接受p成功的回调return '11112222'    }, reason => { });
console.log(p1);     //输出p1这个promise对象

        const p1 = p.then(value => { }, reason => {   //接受p失败的回调return '33334444'});console.log(p1);   // 此时p1的状态还是fulfilled,证明只和回调函数的返回结果有关系

2.如果回调函数的返回结果是promise对象,则p1的状态就取决于return返回的这个promise对象内部的状态,内部为resolve, 则p1状态为fulfilled,内部为reject,则p1状态为rejected

        const p1 = p.then(value => {return new Promise((resolve, reject) => {reject('出错了')})}, reason => { });console.log(p1);   //结果为rejected

3.第三种情况为抛出错误,则p1状态为rejected,返回的结果就是你抛出的值

        const p1 = p.then(value => {// throw new Error('出错了');throw '出错了';    //没有return,直接抛出错误}, reason => { });console.log(p1);

二、改变promise对象的状态(非then方法中)

实例化一个promise对象,接受一个函数类型的值,里面可以封装异步操作。状态的改变只有两条路,进行中pending变为成功resolved,进行中变为失败rejected,而且只会改变一次,不可能从成功变为失败或者失败变为成功。

只有三种方法改变promise对象的状态,resolve/ reject/ throw抛出错误,如果你在promise对象中不去改变他的状态,那么他的状态永远都是pending,也不会去执行回调函数。

        let p = new Promise((resolve, reject) => {resolve('成功数据');    //状态变为 成功resolvedreject('失败数据');     //状态变为 失败rejectedthrow '报错'             //状态变为 失败rejectedthrow new Error('123');   //状态变为 失败rejected})

注意:return并不能改变他的状态,这不是在then方法中,then方法有自己的一套东西。

三、注意点

1、promise对象里面的代码是同步执行的,只是回调函数才是异步执行的,因为你不改变状态就不会去执行回调。而且状态改变后,后续的代码继续执行。

        let p = new Promise((resolve, reject) => {console.log(1);reject('error');console.log(2);});console.log(3);p.catch(reason => {console.log(reason);    //最后输出 ‘error’});console.log(4);结果:1 2 3 4 error

2、指定多个回调都会被执行

        let p = new Promise((resolve, reject) => {resolve('OK');});p.then(value => {console.log(value);});p.then(value => {console.log(value);});输出: ok  ok

3、假设你的promise对象,状态变为失败,但是你的then每次只写成功的回调,那就找不到失败的回调,那么他会顺着链一直往下传递,直到找到失败的回调。这就是异常穿透。同理,你的promise对象,状态变为成功,但是你的链只写catch,那就找不到成功的回调,那么他会顺着链一直往下传递,直到找到成功的回调。

三、async/await

async/await 是ES7提出的基于Promise的解决异步的最终方案。

1、async

async也是一个函数,他和一般的函数不同,他的返回结果是一个promise对象,而且该promise对象的结果是由async函数执行的返回值来决定的,这一点和promise的then的回调函数很像,都是通过返回值来决定状态和结果的。

既然返回promise就可以使用promise的方法,then,all,race

        async function main(){// 1、 return非promise类型的数据return 123;// 2、 return的是promise对象return new Promise((resolve,reject)=>{resolve('success')// reject('error')}) // 3、抛出异常throw '异常'}console.log(main())    //返回promise对象main().then(data=>{console.log(data);},reason=>{console.log(reason);})

2、await + 表达式

await必须写在async函数当中,但是async函数中可以没有await。await可以理解为等待,且等到取到值后语句才会往下执行。await其实说白了就是对promise对象的成功结果进行获取,如果失败就通过catch获取失败的结果。
await的右侧的表达式一般都是promise对象,但也可以是其他值
一、如果表达式是promise对象并且状态为成功,那么await将返回的是这个promise对象成功的值;
二、如果表达式是promise对象,并且它失败了,那么就要通过try,catch进行捕获错误,不捕获错误那么后面代码无法执行。
三、如果不是Promise对象,把这个非promise的东西当做await表达式的结果,如字符串数字等。

async function main(){let p1 = new Promise((resolve,reject)=>{resolve('success')})let p2 = new Promise((resolve,reject)=>{reject('error')})// 1、右侧为promise情况,常用let res1 = await p1;console.log(res1);    // success// 2、右侧为promise情况,并且失败了,失败了没有通过 trycatch 捕获,那后面代码就不会执行了try {let res2 = await p2;} catch (e) {console.log(e);}// 3、右侧为非promise类型的数据let res3 = await 123;console.log(res3);   // 123}main()

promise.then返回结果几种情况相关推荐

  1. 微信退款返回的几种情况

    1.订单已经全额退款返回后再请求退款时: {     "appid": "wx88888888",     "err_code": &quo ...

  2. Promise.resolve几种情况

    Promise.resolve等价于下面的写法 有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用. Promise.resolve('foo') // 等 ...

  3. try catch finally 中包含return的几种情况,及返回结果

    第一种情况:在try和catch中有return,finally中没有return,且finally中没有对try或catch中要 return数据进行操作的代码,这种情况也是最好理解的. publi ...

  4. vue中处理后台返回的 html 特殊标签(‘\lt; p style=“xxx“ \gt;‘)或(\<p>)的三种情况及传给后端数据的解决方案

    问题一:vue中处理后台返回的 html 特殊标签('&lt: p style="xxx" &gt:')或(\<p>)的三种情况 返回数据 // 返回数 ...

  5. 探讨read的返回值的三种情况

    今天探讨一个很看似简单的API "read"的返回值问题.read的返回值有哪几个值?每个值又是在什么情况下发生的? 先问一下男人吧:man 2 read RETURN VALUE ...

  6. No.002 关于Python函数返回值的三种情况

    关于Python函数返回值的三种情况,无返回值.有1个返回值,以及有多个返回值 # 本批次所有文章都是跟着马士兵的杨淑娟老师的视频教学所得,视频地址在下面: # https://www.bilibil ...

  7. 执行update语句,返回受影响行数为0的几种情况

    首先我们都很清楚执行update语句,返回的结果是受影响的行数这是要先说的, 其次本人遇到执行update语句返回0的情况有两种 1.Update的sql语句中的where条件不成立时,返回结果是0 ...

  8. mysql返回Boolean类型的几种情况

    第一种情况,直接返回 select id='22aa' from mytest where age=202 返回1 可封装为true select count(*)=1 from mytest whe ...

  9. dom不刷新 vue 加数据后_详解Vue 数据更新了但页面没有更新的 7 种情况汇总及延伸总结...

    如果你发现你自己需要在 vue 中做一次强制更新,99.9% 的情况,是你在某个地方做错了事. 1. vue 无法检测实例被创建时不存在于 data 中的 property 原因:由于 vue 会在初 ...

最新文章

  1. node.js cannot find module
  2. SEO基础知识8大精华文章之第三篇 SEO的历史(连载)
  3. asp.net mvc 3 RTM 发布了!
  4. Android 高级UI设计笔记20:RecyclerView 的详解之RecyclerView添加Item点击事件
  5. [云炬python3玩转机器学习笔记] 2-7开发环境搭建笔记
  6. php think cmf,thinkphp cmf代码
  7. 计算机编程常用指令,加工中心几个常用指令的编程技巧
  8. 【Deep Learning 二】课程一(Neural Networks and Deep Learning),第二周(Basics of Neural Network programming)答案
  9. 华为服务器双系统教程,双系统安装教程
  10. 学会用Word制作拼音田字格练习本,简单实用更省钱,宝妈必学
  11. JavaScript对JSON数组操作。数组添加(push)以及移除(splitce)
  12. 指针式仪表自动读数与识别(四):非圆形表盘定位
  13. 知识图谱技术原理介绍
  14. SpringBoot项目实战:员工管理系统
  15. JVM进阶(八)——Stop The World(停顿类型STW)
  16. 大V推荐!安卓放弃java
  17. background-size 之 背景图的尺寸设置
  18. BAT开源项目哪家强,这15个开源项目告诉你答案
  19. 如何进入电商直播行业?直播平台有哪些选择?
  20. 国际化项目时区问题解决方案

热门文章

  1. mysql prefix_mysql改变innodb_large_prefix
  2. 论一个X倒下了千千万万个X站起来了
  3. 运动学习与控制-学习笔记(三)——运动控制理论
  4. Foxmail 本地邮箱密码破解思路方法分享
  5. 归并排序算法(C语言)
  6. 机器学习之经典算法(十一) 条件随机场
  7. 计算机最主要的硬盘,电脑硬盘应该分几个区比较合适?
  8. 前端涨薪必读,node.js入门保姆级教程
  9. 区分map和fileter
  10. C++:使用vector中accumulate求和计算出错