JavaScript promise的使用和原理分析

 更新时间:2023年04月12日 09:59:34   作者:肥肥呀呀呀  
Promise 是一个 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务。由于 Promise 是 ES6 新增加的,所以一些旧的浏览器并不支持,苹果的 Safari 10 和 Windows 的 Edge 14 版本以上浏览器才开始支持 ES6 特性

一、为什么一个promise可以调用多个.then方法

如下面的:

const promise = new Promise((resolve, reject) => {
  resolve("hahaha")
})
// 1.同一个Promise可以被多次调用then方法
// 当我们的resolve方法被回调时, 所有的then方法传入的回调函数都会被调用
promise.then(res => {
  console.log("res1:", res)    //hahaha
})
promise.then(res => {
  console.log("res2:", res)    //hahaha
})
promise.then(res => {
  console.log("res3:", res)    //hahaha
})

答案:

  • then内回调 不返回任何值,默认返回当前Promise
  • then内回调 返回Promise
  • then内回调 返回 普通值(数值/字符串/普通对象/undefined),普通的值被作为一个新的Promise的resolve值

二、什么是Promise.resolve()

Promise.resolve() 表示状态为fulfilled的promise对象

Promise.resolve()
// 等同于
new Promise((resolve)=>{resolve()})

为什么会有下面的执行结果? 感觉十分异常

Promise.resolve().then(() => {
  console.log(0);
  return Promise.resolve(4)
}).then(res => {
  console.log(res)
})
Promise.resolve().then(() => {
  console.log(1);
}).then(() => {
  console.log(2);
}).then(() => {
  console.log(3);
}).then(() => {
  console.log(5);
}).then(() =>{
  console.log(6);
})
// 0,1,2,3,4,5,6
(
  async function() {
    return Promise.resolve()
  }
)().then(()=>{
  console.log(1)
})
new Promise((resolve) => {
  resolve()
}).then(()=>{
  console.log(2)
}).then(()=>{
  console.log(3)
})
/// 2 3 1

答案:

如果promise内返回的对象具有可调用的then方法,则会在微任务队列中再插入一个任务NewPromiseResolveThenableJob,这就慢了一拍;这个任务会执行这个then方法,如果这个then方法是来自于promise的,则因为是异步的又慢了一拍,所以一共慢了两拍。

参考

三、Promise.all缺陷和Promise.allSettled

Promise.all() 的缺陷

其中任意一个 promise 被 reject ,Promise.all 就会立即被 reject ,不在执行then。

数组中其它未执行完的 promise 依然是在执行的,但是Promise.all 没有返回它们的结果,同时Promise.all 没有采取任何措施来取消它们的执行。

Promise.allSettled()

Promise.allSettled() 可以获取数组中每个 promise 的结果,无论成功或失败

只有then方法 所有结果都会在then中体现

注意

彼此相互依赖,一个失败全部失效(全无或全有)用 Promise.all ;相互独立,获取每个结果用 Promise.allSettled

四、Promise.race() 使用

多个promise执行,最快的执行Promise.race()的then或者catch

里面的promise依旧会执行

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise 1 resolved');
      console.log(0)
  }, 1000);
});
const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
      console.log(2)
    resolve('Promise 2 resolved');
  }, 2000);
});
Promise.race([promise1, promise2]).then(result => {
  console.log(result); // "Promise 1 resolved"
});
// 0
//Promise 1 resolved
//2

到此这篇关于JavaScript promise的使用和原理分析的文章就介绍到这了,更多相关JS promise内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 全面了解JavaScript的作用域链

    全面了解JavaScript的作用域链

    这是一个非常重要的知识点了,了解了JavaScript的作用域链的话,能帮助我们理解很多‘异常’问题。文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • javascript中对象的定义、使用以及对象和原型链操作小结

    javascript中对象的定义、使用以及对象和原型链操作小结

    这篇文章主要介绍了javascript中对象的定义、使用以及对象和原型链操作,结合实例形式总结分析了javascript对象操作的常用技巧,需要的朋友可以参考下
    2016-12-12
  • JS 控件事件小结

    JS 控件事件小结

    事件对于控件来说至关重要,控件的消息通信机制使用事件的成本最低,但是对于JS控件来说有一些麻烦需要解决,JS类本身不支持事件,DOM模型支持的事件仅适应于浏览器的DOM节点。所以创建一套事件是我们写控件之前要做的
    2012-10-10
  • js split函数用法总结(从入门到精通)

    js split函数用法总结(从入门到精通)

    js split就是将一字符串以特定的字符分割成数组,数组一般是字符串处理比较常用的处理方法
    2013-03-03
  • JavaScript错误处理和调试方法详解

    JavaScript错误处理和调试方法详解

    代码审查是调试JavaScript的重要方法,因为它允许多个开发人员一起处理代码库并在开发过程的早期发现错误,这篇文章主要给大家介绍了关于JavaScript错误处理和调试方法的相关资料,需要的朋友可以参考下
    2023-11-11
  • javascript中的面向对象

    javascript中的面向对象

    本文主要介绍了javascript中面向对象的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-03-03
  • JavaScript返回当前会话cookie全部键值对照的方法

    JavaScript返回当前会话cookie全部键值对照的方法

    这篇文章主要介绍了JavaScript返回当前会话cookie全部键值对照的方法,涉及javascript操作cookie的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-04-04
  • 判断“命令按钮”是否被鼠标单击详解

    判断“命令按钮”是否被鼠标单击详解

    在本篇文章里小编给各位分享的是关于判断“命令按钮”是否被鼠标单击的相关知识点内容,有需要的朋友们参考下。
    2019-07-07
  • 微信小程序实现收缩式菜单

    微信小程序实现收缩式菜单

    这篇文章主要为大家详细介绍了微信小程序实现收缩式菜单,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • filters.revealTrans.Transition使用方法小结

    filters.revealTrans.Transition使用方法小结

    有看到幻灯片调用会用到divid.filters.revealTrans.Transition=Math.floor(Math.random()*23)和divid.filters.revealTrans.apply(),那么这两个都是什么意思呢?
    2010-08-08

最新评论