这 10 个片段,有助于你理解 ES 中的 Promise

更新日期: 2020-02-29阅读量: 760标签: Promise

在开发中,了解 JavaScript 和 Promise 基础,有助于提高我们的编码技能,今天,我们一起来看看下面的 10 片段,相信看完这 10 个片段有助于我们对 Promise 的理解。

片段1:

const prom = new Promise((res, rej) => {
  console.log('first');
  res();
  console.log('second');
});
prom.then(() => {
  console.log('third');
});
console.log('fourth');

// first
// second
// fourth
// third

Promise同步执行,promise.then异步执行。

片段2:

const prom = new Promise((res, rej) => {
  setTimeout(() => {
    res('success');
  }, 1000);
});
const prom2 = prom.then(() => {
  throw new Error('error');
});

console.log('prom', prom);
console.log('prom2', prom2);

setTimeout(() => {
  console.log('prom', prom);
  console.log('prom2', prom2);
}, 2000);

// prom 
// Promise {<pending>}
// __proto__: Promise
// [[PromiseStatus]]: "resolved"
// [[PromiseValue]]: "success"

// 2 秒后还会在打一遍上面的两个

promise 有三种不同的状态:

  • pending
  • fulfilled
  • rejected

一旦状态更新,pending->fulfilled 或pending->rejected,就可以再次更改它。 prom1与prom2不同,并且两者都返回新的Promise状态。

片段3:

const prom = new Promise((res, rej) => {
  res('1');
  rej('error');
  res('2');
});

prom
  .then(res => {
    console.log('then: ', res);
  })
  .catch(err => {
    console.log('catch: ', err);
  });

// then: 1

即使reject后有一个resolve调用,也只能执行一次resolve或reject ,剩下的不会执行。

片段 4:

Promise.resolve(1)
  .then(res => {
    console.log(res);
    return 2;
  })
  .catch(err => {
    return 3;
  })
  .then(res => {
    console.log(res);
  });

// 1
// 2

Promises 可以链接调用,当提到链接调用 时,我们通常会考虑要返回 this,但Promises不用。 每次 promise 调用.then或.catch时,默认都会返回一个新的 promise,从而实现链接调用。

片段 5:

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('first')
    resolve('second')
  }, 1000)
})

const start = Date.now()
promise.then((res) => {
  console.log(res, Date.now() - start, "third")
})
promise.then((res) => {
  console.log(res, Date.now() - start, "fourth")
})

// first
// second 1054 third
// second 1054 fourth

promise 的 .then或.catch可以被多次调用,但是此处Promise构造函数仅执行一次。 换句话说,一旦promise的内部状态发生变化并获得了一个值,则随后对.then或.catch的每次调用都将直接获取该值。

片段 6:

const promise = Promise.resolve()
  .then(() => {
    return promise
  })
promise.catch(promise )

// [TypeError: Chaining cycle detected for promise #<Promise>]
// Uncaught SyntaxError: Identifier 'promise' has already been declared
//    at <anonymous>:1:1
// (anonymous) @ VM218:1

.then或.catch返回的值不能是promise本身,否则将导致无限循环。

片段 7:

Promise.resolve()
  .then(() => {
    return new Error('error');
  })
  .then(res => {
    console.log('then: ', res);
  })
  .catch(err => {
    console.log('catch: ', err);
  });

// then: Error: error!
// at Promise.resolve.then (...)
// at ...

在.then或.catch中返回错误对象不会引发错误,因此后续的.catch不会捕获该错误对象,需要更改为以下对象之一:

return Promise.reject(new Error('error')) throw new Error('error')

因为返回任何非promise 值都将包装到一个Promise对象中,也就是说,返回new Error('error')等同于返回Promise.resolve(new Error('error'))。

片段 8:

Promise.resolve(1)
  .then(2)
  .then(Promise.resolve(3))
  .then(console.log)

  // 1

.then或.catch的参数应为函数,而传递非函数将导致值的结果被忽略,例如.then(2)或.then(Promise.resolve(3)。

片段 9:

Promise.resolve()
  .then(
    function success(res) {
      throw new Error('Error after success');
    },
    function fail1(e) {
      console.error('fail1: ', e);
    }
  )
  .catch(function fail2(e) {
    console.error('fail2: ', e);
  });

//   fail2:  Error: Error after success
//     at success (<anonymous>:4:13)

.then可以接受两个参数,第一个是处理成功的函数,第二个是处理错误的函数。 .catch是编写.then的第二个参数的便捷方法,但是在使用中要注意一点:.then第二个错误处理函数无法捕获第一个成功函数和后续函数抛出的错误。 .catch捕获先前的错误。 当然,如果要重写,下面的代码可以起作用:

Promise.resolve()
  .then(function success1 (res) {
    throw new Error('success1 error')
  }, function fail1 (e) {
    console.error('fail1: ', e)
  })
  .then(function success2 (res) {
  }, function fail2 (e) {
    console.error('fail2: ', e)
  })

片段 10:

process.nextTick(() => {
  console.log('1')
})
Promise.resolve()
  .then(() => {
    console.log('2')
  })
setImmediate(() => {
  console.log('3')
})
console.log('4');

// Print 4
// Print 1
// Print 2
// Print 3

process.nextTick和promise.then都属于微任务,而setImmediate属于宏任务,它在事件循环的检查阶段执行。 在事件循环的每个阶段(宏任务)之间执行微任务,并且事件循环的开始执行一次。

原文:http://jamesknelson.com/
作者:Jay Chow
译者:前端小智


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: https://www.fly63.com/article/detial/8455

vue中利用Promise封装jsonp并调取数据

Promise就是一个给一步操作提供的容器,在这个容器里,有两个阶段无法改变的阶段,第一个阶段就是Pending(进行),第二个阶段就是结果阶段,包含Fulfilled(成功)、Rejected(失败)两个结果

ES6之Promise

所谓的 promise,简单的来说就是一个容器,里面保存着某个未来才会结束的事件(也就是我们的异步操作)的结果。从语法上面来说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

这样理解 promise

官网解释 promise 表示一个异步操作的最终结果。翻译 ==可以将promise理解为一个状态机==,它存在三种不同的状态,并在某一时刻只能有一种状态,一个promise是对一个异步操作的封装

Promise 对象的理解

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了 Promise 对象。

如何使用Promise.race() 和 Promise.any() ?

自1996年发布以来,JS 一直在稳步改进。随着ECMAScript版本的许多改进,最近的版本是ES2020。JS 的一个重要更新是Promise,在2015年,它以 ES6 的名义发布。

你真的懂Promise吗

在异步编程中,Promise 扮演了举足轻重的角色,比传统的解决方案(回调函数和事件)更合理和更强大。可能有些小伙伴会有这样的疑问:2020年了,怎么还在谈论Promise?

纯手写Promise,由浅入深

首先我们应该知道Promise是通过构造函数的方式来创建的(new Promise( executor )),并且为 executor函数 传递参数:再来说一下Promise的三种状态: pending-等待, resolve-成功, reject-失败, 其中最开始为pending状态

掌握 Promise 的逻辑方法

Promise 是 ES2015 新增的对象:Promise 对象有几个组合方法,可以将多个承诺合并成一个进行处理,分别是 Promise.all, Promise.race, Promise.allSettled, Promise.any,这些方法都可以接收一组承诺,返回一个新的承诺

为promise增加abort功能

Promise只有三种状态:pending、resolve、reject,一个异步的承诺一旦发出,经历等待(pending)后,最终只能为成功或者失败,中途无法取消(abort)。

ES6 Promise实战练习题目

俗话说得好,一动不动是王八,上一篇文章学习了那么久Promise,是时候大显身手了!解析:Promise 构造函数是同步执行的,promise.then 中的函数是异步执行的。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!