参考:

EC前端 - Promise - http://www.ecmaer.com/javascript/nativeObj/promise.html

关于Promise:

  • 什么是 Promise?

    Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。现已被 ES6 纳入进规范中。

    Promise是一个方案,用来解决多层回调嵌套的解决方案

Promise 的常规写法:

  1. new Promise(请求1)
  2. .then(请求2(请求结果1))
  3. .then(请求3(请求结果2))
  4. .then(请求4(请求结果3))
  5. .then(请求5(请求结果4))
  6. .catch(处理异常(异常信息))

Promise 的写法更为直观,并且能够在外层捕获异步函数的异常信息

  • Promise 解决的痛点是什么?

    回调地狱

    需要根据前一个网络请求的结果,再去执行下一个网络请求,代码大概如下:
  1. 请求1(function(请求结果1){
  2. 请求2(function(请求结果2){
  3. 请求3(function(请求结果3){
  4. 请求4(function(请求结果4){
  5. 请求5(function(请求结果5){
  6. 请求6(function(请求结果3){
  7. ...
  8. })
  9. })
  10. })
  11. })
  12. })
  13. })

回调地狱带来的负面作用有以下几点:

1、代码臃肿;

2、可读性差;

3、耦合度过高,可维护性差;

4、代码复用性差;

5、容易滋生 bug;

6、只能在回调里处理异常;

为了能使用一种更加友好的代码组织方式,解决异步嵌套的问题:

  1. let 请求结果1 = 请求1();
  2. let 请求结果2 = 请求2(请求结果1);
  3. let 请求结果3 = 请求3(请求结果2);
  4. let 请求结果4 = 请求2(请求结果3);
  5. let 请求结果5 = 请求3(请求结果4);
  • Promise 的业界实现都有哪些?

    业界著名的 Q 和 bluebird,bluebird 甚至号称运行最快的类库

  • Promise 解决的痛点还有其他方法可以解决吗?如果有,请列举。

    为了解决“回调地狱”,我们可以使用文中所述的这五种常用方法:

    1、function拆解

    回调嵌套所带来的一个重要问题就是代码不易阅读与维护。因为普遍来说,过多的缩进(嵌套)会极大的影响代码的可读性。基于这一点,

    可以进行一个最简单的优化——将各步拆解为单个的function

    2、事件发布/订阅模式

    我们可以监听某一事件,当事件发生时,进行相应回调操作;另一方面,当某些操作完成后,通过发布事件触发回调。这样就可以将原本捆绑在一起的代码解耦。

    3、Promise

    4、Generator

    generator是es6中的一个新的语法。在function关键字后添加*即可将函数变为generator

  1. const gen = function* () {
  2. yield 1;
  3. yield 2;
  4. return 3;
  5. }
  6. let g = gen();
  7. g.next(); // { value: 1, done: false }
  8. g.next(); // { value: 2, done: false }
  9. g.next(); // { value: 3, done: true }
  10. g.next(); // { value: undefined, done: true }

generator函数有一个最大的特点,可以在内部执行的过程中交出程序的控制权,yield相当于起到了一个暂停的作用;而当一定情况下,外部又将控制权再移交回来

5、async / await

es7中的async/await

在async函数中可以使用await语句。await后一般是一个Promise对象

  1. async function foo () {
  2. console.log('开始');
  3. let res = await post(data);
  4. console.log(`post已完成,结果为:${res}`);
  5. };

4、Promise 如何使用?

  1. // 声明函数
  2. function run(callback) {
  3. let parmas = 0;
  4. if (callback) callback(parmas);
  5. };
  6. function fnStep1(callback) {
  7. let parmas = 123;
  8. if (callback) callback(parmas);
  9. };
  10. function fnStep2(callback) {
  11. let parmas = 456;
  12. if (callback) callback(parmas);
  13. };
  14. function fnStep3(callback) {
  15. let parmas = 789;
  16. if (callback) callback(parmas);
  17. };
  18. // fnStep4 ...
  19. // 传统使用回调的写法
  20. run(function (parmas) {
  21. // parmas = 0
  22. console.log(parmas);
  23. fnStep1(function (parmas1) {
  24. // parmas = 123
  25. console.log(parmas1);
  26. fnStep2(function (parmas2) {
  27. // parmas = 456
  28. console.log(parmas2);
  29. fnStep3(function (parmas3) {
  30. // ...
  31. // 一直嵌套
  32. });
  33. });
  34. });
  35. });
  36. let p = new Promise((resolve, reject) => {
  37. const parmas = 0;
  38. resolve(parmas); // fulfilled
  39. // reject("failure reason"); // rejected
  40. })
  41. p.then(
  42. (parmas) => {
  43. // parmas,resolve返回的值
  44. console.log(parmas); //0
  45. return 123; //返回值给下一个then
  46. }
  47. )
  48. .then(
  49. (parmas) => {
  50. // parmas,上一个then返回的值
  51. console.log(parmas); //123
  52. return 456; //返回值给下一个then
  53. }
  54. )
  55. .then(
  56. (parmas) => {
  57. // parmas,上一个then返回的值
  58. console.log(parmas); //456
  59. return 789; //返回值给下一个then
  60. })
  • Promise 常用的方法,方法的作用?

    1、race

    多个promise 任务同时执行,只返回最先执行完的 Promise 任务的结果;

    2、all

    多个promise 任务同时执行,返回所有promise 任务的执行结果;

6、Promise 在事件循环中的执行过程是怎样的?

  • 构造函数传入的参数是什么类型?

    它接收的参数是一个匿名函数,任何情况下,它里面的js最先执行。

    这个匿名函数也有二个参数:

    1、resolve,完成,操作成功时调用。

    2、reject,失败,操作失败时调用。

  • 传入的该函数是会立刻执行的吗?

    会在本次new 操作立刻执行。

    第一次resolve就确定了自己是成功还是失败。第二次没用了。添加reject也改变不了

  • 若调用了两次resolve方法会怎么样?

    只执行第一次resolve

  • 发生异常会怎么样?

    promise的原理?jquery的ajax返回的是promise对象吗?(百度面试)

    promise 只有2个状态,成功和失败,怎么让一个函数无论成功和失败都能被调用?

    Promise.all() 是干什么用的,怎么用?

  • 初始化Promise对象的方法

    new Promise(fn)

    Promise.resolve(fn)

  1. /*
  2. *end
  3. *nextTick
  4. *then
  5. *setImmediate
  6. *
  7. *process.nextTick 和 promise.then 都属于 microtask
  8. * 而 setImmediate 属于 macrotask
  9. * 在事件循环的 check 阶段执行
  10. * 事件循环的每个阶段(macrotask)之间都会执行 microtask,事件循环的开始会先执行一次 microtask
  11. *
  12. */
  13. process.nextTick(()=>{
  14. console.log('nextTick');
  15. });
  16. Promise.resolve().then(()=>{
  17. console.log('then');
  18. });
  19. setImmediate(()=>{
  20. console.log('setImmediate');
  21. });
  22. console.log('end');

Promise扩展之事件循环机制:

macrotasks:

  • setTimeout
  • setInterval
  • setImmediate
  • requestAnimationFrame
  • I/O
  • UI rendering

microtasks:

  • process.nextTick
  • Promises
  • Object.observe
  • MutationObserver

任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。

同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;

异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

执行优先级的问题 microtasks > macrotasks

在每一次事件循环中,macrotask 只会提取一个执行,而 microtask 会一直提取,直到 microtasks 队列清空。

而事件循环每次只会入栈一个 macrotask ,主线程执行完该任务后又会先检查 microtasks 队列并完成里面的所有任务后再执行 macrotask

  1. setImmediate(function(){
  2. console.log(1);
  3. },0);
  4. setTimeout(function(){
  5. console.log(2);
  6. },0);
  7. new Promise(function(resolve){
  8. console.log(3);
  9. resolve();
  10. console.log(4);
  11. }).then(function(){
  12. console.log(5);
  13. });
  14. console.log(6);
  15. process.nextTick(function(){
  16. console.log(7);
  17. });
  18. console.log(8);
  19. //3 4 6 8 7 5 2 1

认识JavaScript Promise的更多相关文章

  1. [Javascript] Promise

    Promise 代表着一个异步操作,这个异步操作现在尚未完成,但在将来某刻会被完成. Promise 有三种状态 pending : 初始的状态,尚未知道结果 fulfilled : 代表操作成功 r ...

  2. Javascript Promise 学习笔记

    1.     定义:Promise是抽象异步处理对象以及对其进行各种操作的组件,它把异步处理对象和异步处理规则采用统一的接口进行规范化. 2.     ES6 Promises 标准中定义的API: ...

  3. 【译】JavaScript Promise API

    原文地址:JavaScript Promise API 在 JavaScript 中,同步的代码更容易书写和 debug,但是有时候出于性能考虑,我们会写一些异步的代码(代替同步代码).思考这样一个场 ...

  4. JavaScript Promise:去而复返

    原文:http://www.html5rocks.com/en/tutorials/es6/promises/ 作者:Jake Archibald 翻译:Amio 女士们先生们,请准备好迎接 Web ...

  5. javaScript Promise 入门

    Promise是JavaScript的异步编程模式,为繁重的异步回调带来了福音. 一直以来,JavaScript处理异步都是以callback的方式,假设需要进行一个异步队列,执行起来如下: anim ...

  6. JavaScript Promise异步实现章节的下载显示

    Links: JavaScript Promise:简介 1.一章一章顺序地下载显示下载显示 使用Array.reduce()和Promise.resolve()将各章的下载及显示作为整体串联起来. ...

  7. Javascript - Promise学习笔记

    最近工作轻松了点,想起了以前总是看到的一个单词promise,于是耐心下来学习了一下.   一:Promise是什么?为什么会有这个东西? 首先说明,Promise是为了解决javascript异步编 ...

  8. Javascript Promise入门

    是什么? https://www.promisejs.org/ What is a promise? The core idea behind promises is that a promise r ...

  9. JavaScript Promise API

    同步编程通常来说易于调试和维护,然而,异步编程通常能获得更好的性能和更大的灵活性.异步的最大特点是无需等待."Promises"渐渐成为JavaScript里最重要的一部分,大量的 ...

  10. 【JavaScript】JavaScript Promise 探微

    http://www.html-js.com/article/Promise-translation-JavaScript-Promise-devil-details 原文链接:JavaScript ...

随机推荐

  1. 由2个鸡蛋从100层楼下落到HashMap的算法优化联想

    题目: 有一栋楼共100层,一个鸡蛋从第N层及以上的楼层下落会摔破,在第N层以下的楼层不会摔破,给你两个鸡蛋,设计方案找出N,并且保证在最坏的情况下,最小化鸡蛋下落的次数.(鸡蛋没有摔破是可以重复利用 ...

  2. ajax请求中包含中文参数

    对需要传递的中文参数先进行两次转码: 1.js文件中使用encodeURI()方法. var url = "Validate.jsp?id=" + encodeURI(encode ...

  3. ADB抓取内存命令

    1. 在IDE中查看Log信息当程序运行垃圾回收的时候,会打印一条Log信息,其格式如下:D/dalvikvm: <GC_Reason> <Amount_freed>, < ...

  4. Linux 下安装 tomcat

    前提:已经安装配置好了 JDK 1.下载二进制文件 wget http://us.mirrors.quenda.co/apache/tomcat/tomcat-9/v9.0.19/bin/apache ...

  5. 供Linux学习使用的在线模拟系统

    前言 我只是一名搬运工. 最近想要找一个linux服务器用于调试shell脚本,但是公司服务器又只能内网访问,外网无法使用.对安装VMWARE+Linux镜像觉得繁琐.查找了一下资料.找到了几个在线模 ...

  6. Spring再接触 Annotation part2

    resource resource beans.xml <?xml version="1.0" encoding="UTF-8"?> <bea ...

  7. MemoryStream说明

    MemoryStream 是内存流,为系统内存提供读写操作,由于 MemoryStream 是通过无符号字节数组组成的,可以说 MemoryStream 的性能可以算比较出色,所以它担当起了一些其他流 ...

  8. 2018.5.12 storm数据源kafka堆积

    问题现象: storm代码依赖4个源数据topic,2018.5.12上午8点左右开始收到告警短信,源头的4个topic数据严重堆积. 排查: 1.查看stormUI, storm拓扑结构如下: 看现 ...

  9. 关于创建String对象过程的内存分配

    String是引用数据类型 但是String实际上java给我们提供的是一个类 注意:String 全类被fianl所修饰 所以 String 又叫 字符串常量 String 的值 一旦定义 不可以改 ...

  10. Masonry与AmazeUI结合实现瀑布流

    做一个图片列表展示,由于照片数量太多,决定用瀑布流来实现 由于之前没有接触过瀑布流,不知从何下手 百度一下大家都在用Masonry 官网 https://masonry.desandro.com/ 这 ...