通俗浅显的理解promise中的then

  • 先看一下下面4个Promise到底有什么区别呢?
  • 执行第一个方法:
  • 执行第二个方法:
  • 执行第三个方法:
  • 执行第四个方法:

文章原文出处:博主petruslaw

Promise,ES6中定义的规范,不会使用Promise,都不敢说自己用过ES6,大部分介绍Promise的规范的文章对于新手小白来说看得云里雾里,且并不是通俗易懂。本文通过实例介绍讲述Promise中then的的最通俗应用理解,代码建立在不出现异常的情况的操作下,不严谨之处,请以官方规范为标准。

先看一下下面4个Promise到底有什么区别呢?

func().then(function () {return cb();
});func().then(function () {cb();
});func().then(cb());func().then(cb);

如果你知道答案,以下内容你可以不用继续。

上面的代码过于简单,运行时话需要稍微进行一点扩展,每个方法中都打印出promise上一步的调用值,为了方便我给每个方法加了一个下标输出,分别是1、2、3、4。

let func = function() {return new Promise((resolve, reject) => {resolve('返回值');});/*resolve和reject是函数,接收函数的函数是高阶函数。此处的高阶函数就是Promise()内部代码整体(匿名箭头函数)。      箭头函数内部没有this,其this指向箭头函数的上一个临近函数/对象。*/
};let cb = function() {return '新的值';
}func().then(function () {return cb();
}).then(resp => {console.warn(resp);console.warn('1 =========<');
});func().then(function () {cb();
}).then(resp => {console.warn(resp);console.warn('2 =========<');
});func().then(cb()).then(resp => {console.warn(resp);console.warn('3 =========<');
});func().then(cb).then(resp => {console.warn(resp);console.warn('4 =========<');
});

不卖关子,直接看结果

首先要明白Promise中then方法会干什么事情!

官方文档是这样定义的:

一个 promise 必须提供一个 then 方法以访问其当前值、终值和据因。
promise 的 then 方法接受两个参数:

promise.then(onFulfilled, onRejected) Todo:这里只介绍onFulfilled,所以删除了关于onRejected的规范定义

onFulfilled 和 onRejected 都是可选参数。

如果 onFulfilled 不是函数,其必须被忽略
如果 onFulfilled 是函数:

当 promise 执行结束后其必须被调用,其第一个参数为 promise 的终值
在 promise 执行结束前其不可被调用
其调用次数不可超过一次

用通(ren)俗(hua)的话来说:
then方法提供一个供自定义的回调函数,若传入非函数,则会忽略当前then方法。
回调函数中会把上一个then中返回的值当做参数值供当前then方法调用。
then方法执行完毕后需要返回一个新的值给下一个then调用(没有返回值默认使用undefined)。
每个then只可能使用前一个then的返回值。

直观的图:

有了上面的定义我们带着三个疑问来回答问题:

  1. 上一个then中传入了回调函数吗?
  2. 上一个then中提供了返回值吗?
  3. 若上一个then中若提供了返回值,返回了什么?

执行第一个方法:

func().then(function () {return cb();
}).then(resp => {console.warn(resp);console.warn('1 =========<');
});

function () {return cb();
}

显而易见,是传入了回调函数的
回调函数中把cb执行后的返回值当做then中的返回值,所以输出了“新的值”;

执行第二个方法:

func().then(function () {cb();
}).then(resp => {console.warn(resp);console.warn('2 =========<');
});

function () {cb();
}

then回调方法,只是执行了cb方法,并没有return值,定义中讲过若then没有返回值,提供给下一个then使用的参数就是undefined,所以打印出来的是undefined;

执行第三个方法:

func().then(cb()).then(resp => {console.warn(resp);console.warn('3 =========<');
});


then中cb()执行后返回的并不是一个函数,在Promise规范中会自动忽略调当前then,所以会把func中的返回值供下一个then使用,输出了“返回值”

执行第四个方法:

func().then(cb).then(resp => {console.warn(resp);console.warn('4 =========<');
});


第一个方法在回调内部返回cb执行后的值,第四个方法则直接把cb当做回调,第一个方法与第四个方法异曲同工之妙,所以也输出了“新的值”。

题目出处:link
Promise规范:link

通俗浅显的理解promise中的then相关推荐

  1. 深入理解nodejs中的异步编程

    文章目录 简介 同步异步和阻塞非阻塞 javascript中的回调 回调函数的错误处理 回调地狱 ES6中的Promise 什么是Promise Promise的特点 Promise的优点 Promi ...

  2. 大白话讲解Promise(二)理解Promise规范

    上一篇我们讲解了ES6中Promise的用法,但是知道了用法还远远不够,作为一名专业的前端工程师,还必须通晓原理.所以,为了补全我们关于Promise的知识树,有必要理解Promise/A+规范,理解 ...

  3. [转]深入理解CSS中的层叠上下文和层叠顺序

    http://www.zhangxinxu.com/wordpress/2016/01/understand-css-stacking-context-order-z-index/ 零.世间的道理都是 ...

  4. 如何简单地理解Python中的if __name__ == '__main__'

    如何简单地理解Python中的if __name__ == '__main__' 文章目录: 一.摘要 二. 程序入口 虽然已经知道这个具体的用法,但是这篇文章有很多细节写的还是很好,决定转载一下,日 ...

  5. php event loop,理解javascript中的事件循环(Event Loop)

    背景 在研究js的异步的实现方式的时候,发现了JavaScript 中的 macrotask 和 microtask 的概念.在查阅了一番资料之后,对其中的执行机制有所了解,下面整理出来,希望可以帮助 ...

  6. es5如何实现promise_彻底理解Promise对象——用es5语法实现一个自己的Promise(上篇)...

    众所周知javascript语言的一大特色就是异步,这既是它的优点,同时在某些情况下也带来了一些的问题.最大的问题之一,就是异步操作过多的时候,代码内会充斥着众多回调函数,乃至形成回调金字塔.为了解决 ...

  7. ES6——举个例子理解Promise的原理和使用

    1. Promise 之前 1.1 回调函数 回调函数:把函数A当作参数传递给另一个函数B调用,那么A就是回调函数. 一些例子 具名回调 function 你有几只狗(fn){fn('一只狗') } ...

  8. java 值栈的结构_Struts2 | 深入浅出理解struts2中的值栈

    在没有struts框架的时候,我们通常在Servlet中使用域对象进行存值和取值,将其作为载体来承载页面和后台之间的数据传递. 在struts2中,我们又有了一种新的机制来进行数据的传递. 那就是st ...

  9. SVM支持向量机通俗导论(理解SVM的三层境界)

    神文 转自july:http://blog.csdn.net/v_july_v/article/details/7624837 支持向量机通俗导论(理解SVM的三层境界) 作者:July .致谢:pl ...

最新文章

  1. Java String 到底是引用传递还是值传递?
  2. Linux 基础知识(十)DNS服务器主从复制,子域授权
  3. stc单片机入门c语言,谈谈单片机入门
  4. php content-type: multipart/mixed,{error:invalid multipart format} 这是什么原因,我已经在HEADER中设置了Content-...
  5. 面向对象--内置方法
  6. leetcode题解191-位1的个数
  7. diff算法_Virtual Dom和Diff算法
  8. Netbeans 安装和配置 C/C++ 支持
  9. ASP.NET AJAX入门系列(7):使用客户端脚本对UpdateProgress编程
  10. Redis实现分布式爬虫
  11. Bailian4074 积水量【序列处理】
  12. 仿抖音上下滑动播放视频
  13. 5G组网方案和频谱规划
  14. 杰理AD14N/AD15N---长按键开关机怎么实现
  15. 算法 图8 How Long Does It Take
  16. SEO新手入门系列2022(五):挖掘关键词
  17. 华为pppoe简单配置实验
  18. 『与善仁』Appium基础 — 3、移动端测试环境搭建(三)之AVD模拟器安装
  19. Bert入门:使用Bert运行MRPC的demo成功案例
  20. Java集合--阻塞队列(LinkedBlockingQueue)

热门文章

  1. C++背包问题——完全背包必须装满的方案数
  2. android手机常用分辨率
  3. 【强化学习实战】基于gym和tensorflow的强化学习算法实现
  4. [编程题] 困兽之斗
  5. Java Socket正确读取数据姿势
  6. 与机器人恋爱?人工智能已开始影响人类伦理观
  7. Endnote中有的文献没有Pages信息怎么办?
  8. signature=37615ca45efe9600a605bfc580bf67ea,止痛药双氯芬酸会显著增加心脏病中风风险
  9. Java 丢手绢游戏 求和_大班游戏活动_丢手绢
  10. JVM之G1垃圾收集器