ECMAScript6中Promise是什么?有什么用?(附示例)

本篇文章给大家带来的内容是关于ecmascript6中promise是什么?有什么用?(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

刚学习完,有点粗略印象。整理记录一下以便后续学习补充,加深理解。

Promise是什么

Promise是构造函数,可以通过new来生成Promise对象。

Promise有什么用

目前我的感受是:更加方便来操作异步流程,更加明确直观的控制事件的流程以及可以链式调用

Promise特点

摘自ES6入门

Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

通过几个简单例子理解它

通过new构造一个简单的Promise对象

let p = new Promise((resolve, reject) => {});

登录后复制

传入的两个参数是用来控制Promise对象的状态,我们打印一下p看一下它的状态:
Promise {__proto__: Promise[[PromiseStatus]]: “pending”[[PromiseValue]]: undefined这个就是初始状态pending
而resolve,reject可以控制Promise的状态

//resolve()let p = new Promise((resolve, reject) => resolve("123")); //Promise {: "123"}

登录后复制

//reject()let p = new Promise((resolve, reject) => reject("123")); //reject()后是返回一个失败状态的Promise,不需要用catch来捕获不写catch会报错p.catch(data => console.log(data));    console.log(p);    //Promise {: "123"}   123

登录后复制

提到了catch那就有还有一个then
 说一直白点:then(f1, f2)可以填入两个函数参数,一个参数就是将resolve中参数代入f1来执行,第二个参数将reject中参数代入f2来执行;第二个参数可以用catch来代替,并且它更加强大,catch能捕获then()中的报错

let p = new Promise((resolve, reject) => {        let n = Math.ceil(Math.random() * 10);    n > 5 ? resolve(n) : reject(n);});p.then(    data => console.log(data),    data => console.log(data),)

登录后复制

用catch代替,并捕获then的错误

let p = new Promise((resolve, reject) => {        resolve("yes")});p.then(    data => {console.log(data),console.log(a)}).catch(data => console.log(data));//yes//ReferenceError: a is not defined

登录后复制

因为then处理后返回的还是Promise对象,这样方便链式调用,then中都没有return,怎么会有Promise对象的呢?

then或catch即使未显式指定返回值, 它们也总是自动包装一个新的fulfilled状态的promise对象。

我们打印一下会发现:Promise {: undefined}
  那么我们可以显示的return一个Promise对象看看,

let p = new Promise((resolve, reject) => resolve("yes"));p.then(data => Promise.resolve("第二个Promise")).then(data => console.log(data));   //第二个Promise

登录后复制

可以看到p.then(data => Promise.resolve(“第二个Promise”))返回Promise对象是Promise {: “第二个Promise”}并且将value值作为参数传入到第二个then中来执行

Promise.resolve(value | promise | thenable)创建Promise对象
  第一参数空或者原始值,创建后的Promise对象状态直接为resolved状态

Promise.resolve('f')// 等价于new Promise(resolve => resolve('f'))

登录后复制

第二值得注意的是具有then方法的对象

let thenable = {    then :(resolve, reject) => resolve("thenable")}let p = Promise.resolve(thenable);console.log(p);

登录后复制

Promise对象状态由->
  第三参数为实例化的Promise对象,

let p1 = new Promise((resolve, reject) => false);let p = Promise.resolve(p1);console.log(p);

登录后复制

p状态和p1状态一致的

Promise.reject(value)创建Promise对象
  与resolve不同的是:直接将value原样作为参数传入

const thenable = {  then(resolve, reject) {    reject('出错了');  }};Promise.reject(thenable).catch(e => {  console.log(e === thenable)})

登录后复制

catch方法的参数不是reject抛出的“出错了”这个字符串,而是thenable对象。

Promise.all

将多个 Promise 实例,包装成一个新的 Promise 实例;const p = Promise.all([p1, p2, p3]);

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

会等all中的对象全部执行完后将数组传入回调函数then中

let p = new Promise((resolve, reject) => setTimeout(() => resolve('p'),1000));let p1 = new Promise((resolve, reject) => setTimeout(() => resolve('p2'),2000));let p2 = new Promise((resolve, reject) => setTimeout(() => resolve('p3'),3000));Promise.all([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));    // ["p", "p2", "p2"]

登录后复制

let p = new Promise((resolve, reject) => resolve('p'));let p1 = new Promise((resolve, reject) => reject('p2'));let p2 = new Promise((resolve, reject) => resolve('p2'));Promise.all([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));   //p2

登录后复制

Promise.race
与all不同的是:只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

let p = new Promise((resolve, reject) => setTimeout(() => resolve('p'),1000));let p1 = new Promise((resolve, reject) => setTimeout(() => resolve('p2'),2000));let p2 = new Promise((resolve, reject) => setTimeout(() => resolve('p3'),3000));Promise.race([p, p1, p2]).then(data => console.log(data)).catch(data => console.log(data));   //p

登录后复制

Promise对象的回调函数与setTimeout的顺序问题

An event loop has one or more task queues. A task queue is an ordered list of tasks, which are algorithms that are responsible for such work as: events, parsing, callbacks, using a resource, reacting to DOM manipulation…Each event loop has a microtask queue. A microtask is a task that is originally to be queued on the microtask queue rather than a task queue.
  浏览器(或宿主环境) 遵循队列先进先出原则, 依次遍历macrotask queue中的每一个task, 不过每执行一个macrotask, 并不是立即就执行下一个, 而是执行一遍microtask queue中的任务, 然后切换GUI线程重新渲染或垃圾回收等.
  Event Loop (事件循环)拥有如下两种队列
  macrotask queue, 指的是宏任务队列, 包括rendering, script(页面脚本), 鼠标, 键盘, 网络请求等事件触发, setTimeout, setInterval, setImmediate(node)等等.
  microtask queue, 指的是微任务队列, 用于在浏览器重新渲染前执行, 包含Promise, process.nextTick(node), Object.observe, MutationObserver回调等.
  process.nextTick > promise.then > setTimeout ? setImmediate

setTimeout(function () {  console.log('three');}, 0);Promise.resolve().then(function () {  console.log('two');});console.log('one');// one// two// three

登录后复制

上面代码中,setTimeout(fn, 0)在下一轮“事件循环”开始时执行,Promise.resolve()在本轮“事件循环”结束时执行,console.log(‘one’)则是立即执行,因此最先输出。

setTimeout(function() {  console.log(4)}, 0);new Promise(function(resolve) {  console.log(1);  for (var i = 0; i < 10000; i++) {    i == 9999 && resolve()  }  console.log(2);}).then(function() {  console.log(5)});console.log(3);  //1 2 3 5 4

登录后复制

以上就是ECMAScript6中Promise是什么?有什么用?(附示例)的详细内容,更多请关注【创想鸟】其它相关文章!

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

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2738240.html

(0)
上一篇 2025年3月8日 01:48:20
下一篇 2025年3月8日 01:48:25

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • js中根据json生成html表格的方法介绍(代码)

    本篇文章给大家带来的内容是关于js中根据json生成html表格的方法介绍(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 之前公司有一个需求是:通过js来生成html。而且大部分都是生成表格,直接通过字符串拼接的话…

    编程技术 2025年3月8日
    000
  • JavaScript中按值传递的详细介绍

    本篇文章给大家带来的内容是关于JavaScript中按值传递的详细介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 概述 参数的传递分为按值传递和按引用传递,而 javascript 中参数的传递只有按值传递。 ECMA…

    2025年3月8日
    200
  • Vue中使用axios请求拦截的方法介绍

    本篇文章给大家带来的内容是关于vue中使用axios请求拦截的方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 一、前言 axios的基础使用就不过多的讲解啦,如何使用可以看axios文档使用说明·Axios中文说明…

    2025年3月8日
    200
  • 带你详细实现vue双向绑定

    本篇文章给大家带来的内容是关于带你详细实现vue双向绑定,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 当今前端天下以 Angular、React、vue 三足鼎立的局面,你不选择一个阵营基本上无法立足于前端,甚至是两个或…

    2025年3月8日 编程技术
    200
  • javascript遍历方法的介绍(代码示例)

    本篇文章给大家带来的内容是关于javascript遍历方法的介绍(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 有用到object对象的转换成数组,然后又想到了遍历方法,所以,也想记录下 1. 终止或者跳出循环…

    编程技术 2025年3月8日
    200
  • JS中原型式和寄生式继承的详解(代码示例)

    本篇文章给大家带来的内容是关于js中原型式和寄生式继承的详解(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 前言:最近在细读Javascript高级程序设计,对于我而言,中文版,书中很多地方翻译的差强人意,所以…

    编程技术 2025年3月8日
    200
  • JavaScript中如何使用String对象?String对象的常用方法

    本篇文章给大家带来的内容是介绍javascript中如何使用string对象?string对象的常用方法 。有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助。 length 返回字符串的长度(字符数) var str=’Hel…

    2025年3月8日 编程技术
    200
  • 本地node包的测试方法介绍

    本篇文章给大家带来的内容是关于本地node包的测试方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 当我们编写一个node包,在发布到npm上之前,需要在本地测试该包。假设我们有一个已经编写好的本地node包xcxu…

    编程技术 2025年3月8日
    200
  • BAT各大互联网公司javascript前端面试题总结

    本篇文章给大家带来的内容是关于bat各大互联网公司javascript前端面试题总结,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 很多面试题是我自己面试BAT亲身经历碰到的。整理分享出来希望更多的前端er共同进步吧,不仅…

    2025年3月8日
    200
  • Node.js的面试题内容总结(附答案)

    本篇文章给大家带来的内容是关于node.js的面试题内容总结(附答案),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 译者按: 从ECMAScript标准,Node.js语法以及NPM模块角度来看,Node.js的发展让人…

    2025年3月8日
    200

发表回复

登录后才能评论