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

做者:Jay Chow
译者:前端小智
来源:jamesknelson

点赞再看,养成习惯前端

本文 GitHub https://github.com/qq44924588... 上已经收录,更多往期高赞文章的分类,也整理了不少个人文档,和教程资料。欢迎Star和完善,你们面试能够参照考点复习,但愿咱们一块儿有点东西。git

在开发中,了解 JavaScript 和 Promise 基础,有助于提升咱们的编码技能,今天,咱们一块儿来看看下面的 10 片断,相信看完这 10 个片断有助于咱们对 Promise 的理解。es6

片断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异步执行。github

片断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->fulfilledpending->rejected,就能够再次更改它。 prom1prom2不一样,而且二者都返回新的Promise状态。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调用,也只能执行一次resolvereject ,剩下的不会执行。服务器

片断 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自己,不然将致使无限循环。工具


你们都说简历没项目写,我就帮你们找了一个项目,还附赠【搭建教程】

我和阿里云合做服务器,折扣价比较便宜:89/年,223/3年,比学生9.9每个月还便宜,买了搭建个项目,熟悉技术栈比较香(老用户用家人帐号买就行了,我用我妈的)推荐买三年的划算点,点击本条就能够查看


片断 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.nextTickpromise.then都属于微任务,而setImmediate属于宏任务,它在事件循环的检查阶段执行。 在事件循环的每一个阶段(宏任务)之间执行微任务,而且事件循环的开始执行一次。


代码部署后可能存在的BUG无法实时知道,过后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给你们推荐一个好用的BUG监控工具 Fundebug

原文:http://jamesknelson.com/grokk...


交流

干货系列文章汇总以下,以为不错点个Star,欢迎 加群 互相学习。

https://github.com/qq44924588...

我是小智,公众号「大迁世界」做者,对前端技术保持学习爱好者。我会常常分享本身所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复福利,便可看到福利,你懂的。

clipboard.png

相关文章
相关标签/搜索