整天困扰着我的javascript Promise问题

如何解决整天困扰着我的javascript Promise问题

此代码如何工作?

new Promise(resolve => {
    new Promise(resolve1 => {
        console.log(1)
        resolve1()
      })
      .then(() => {
        console.log(2)
      })
      .then(() => {
        console.log(3)
      })
    resolve()
  })
  .then(() => {
    console.log(4)
  })

结果为“ 1 2 4 3”

解决方法

最容易理解Promises会发生什么,就是尽可能多地解除链接。

因此,在这种情况下,我们必须记住Promise构造函数是同步运行的,微任务被推入队列(FIFO),并且只有当我们用{{1 }}将解决,使我们的回调将被推送到该队列。

所以我们可以这样重写您的代码段:

.then()

,

// Defining new promise 1
new Promise(resolve => {
    // Defining new promise 2
    new Promise(resolve1 => {
        // print 1
        console.log(1)
        // Resolve promise 1
        resolve1()
    })
        .then(() => {
            // After resolve 1 (then method),print 2
            console.log(2)
        })
        .then(() => {
            // Here we see chain of then methods,so after then 1
            // print 3. But keep in mind,that we also resolves
            // promise 1 before then of promise 2 actually happens,// so now JS doing it's own "parallel" tasks
            // (task/microtask pool,event loop)
            console.log(3)
        })
    // Resolve promise 1
    // BEFORE then from promise 2 completed
    resolve()
})
.then(() => {
    // This then method print 4
    console.log(4)
})

您可以通过添加async / await

来更改此代码并使之异步

// Defining new promise 1
new Promise(async (resolve) => {
    // Defining new promise 2
    await new Promise(resolve1 => {
        // print 1
        console.log(1)
        // Resolve promise 1
        resolve1()
    })
        .then(() => {
            // After resolve 1 (then method),print 2
            console.log(2)
        })
        .then(() => {
            // chain then,prints 3 after first then
            console.log(3)
        })
    // Resolve promise 1
    // AFTER promise 2 complete its then
    resolve()
})
.then(() => {
    // This then method print 4
    console.log(4)
})

,

首先,执行顶层代码: enter image description here

通过执行,两个功能被添加到微任务队列(红色点)。然后,执行微任务队列: enter image description here

将一个功能添加到微任务队列中,然后执行该微任务队列中的功能:

enter image description here

结局。

,

它们是两个单独的promise,并且无论您按什么顺序排列都将并行执行。如果希望获得1、2、3、4的顺序,则必须正确地将它们链接在一起或将它们与Promise.all例如

let outerPromise,innerPromise;

outerPromise = new Promise(resolve => {
    innerPromise = new Promise(resolve1 => {
        console.log(1)
        resolve1()
      })
      .then(() => {
        console.log(2)

      })
      .then(() => {
        console.log(3)
      })
    resolve()
  })
  .then(() => {
    Promise.all([outerPromise,innerPromise]).then(() => console.log(4));
  });

这里是阅读诺言链的好资源-> https://javascript.info/promise-chaining

,

只要调用“ resolve()”即可完成承诺。

JavaScript函数调用也不会阻塞,这意味着当您对某物执行.then时,然后再进行另一个调用,将首先执行第二个调用,然后是第一个调用。与setTimeout等类似的想法

这里

    new Promise(resolve1 => {
        console.log(1)
        resolve1()
    })
        .then(() => {
            console.log(2)
        })
        .then(() => {
            console.log(3)
        })
    resolve()

您首先声明一个新的Promise,该Promise本质上不会控制台记录任何内容(除了1)',该记录仅在.then调用中发生,如前所述,该调用是在(某些)常规函数调用之后执行的然后 然后,您要跟随它的主要解析,并输出4。尽管如此,console.log需要花费一些时间来操作,因此即使2已被控制台记录,但4之前没有足够的时间来记录3。 ,它不依赖于等待诺言链,已被打印

问题?

,

因为要在第三个resolve()被呼叫之前呼叫.then()

它像这样执行...

new Promise(resolve => {
    new Promise(resolve1 => { // okay. we're not waiting. let's keep moving
        console.log(1)
        resolve1(); // oh,yay! let's call .then()
      })
      .then(() => {
        console.log(2) // nothing was returned! let's call .then()
      })
      .then(() => {
        console.log(3) // nothing was returned! let's call .then()
      });
    // this is the next thing to be called after new Promise(resolve1 ...)
    // it will be called almost at the exact same time that resolve1() is called
    resolve(); oh,yay! let's call .then()
  })
  .then(() => {
    console.log(4)
  })

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-