美文网首页WEB前端程序开发web前端经典面试题Web前端之路
什么是Promise,它到底解决了什么问题?

什么是Promise,它到底解决了什么问题?

作者: 全栈弄潮儿 | 来源:发表于2019-08-26 17:25 被阅读15次

什么是Promise

image

Promise 是异步编程的一种解决方案

Promise 核心

  • Promise 概括来说是对异步的执行结果的描述对象。(这句话的理解很重要)
  • Promise 规范中规定了,promise 的状态只有3种:
    • pending
    • fulfilled
    • rejected
      Promise 的状态一旦改变则不会再改变。
  • Promise 规范中还规定了 Promise 中必须有 then 方法,这个方法也是实现异步的链式操作的基本。

ES6 Promise细节

  • Promise 构造器中必须传入函数,否则会抛出错误。(没有执行器还怎么做异步操作。。。)
  • Promise.prototype上的 catch(onrejected) 方法是 then(null,onrejected) 的别名,并且会处理链之前的任何的reject。
  • Promise.prototype 上的 then和 catch 方法总会返回一个全新的 Promise 对象。
  • 如果传入构造器的函数中抛出了错误,该 promise 对象的[[PromiseStatus]]会赋值为 rejected,并且[[PromiseValue]]赋值为 Error 对象。
  • then 中的回调如果抛出错误,返回的 promise 对象的[[PromiseStatus]]会赋值为 rejected,并且[[PromiseValue]]赋值为 Error 对象。
  • then 中的回调返回值会影响 then 返回的 promise 对象。

Promise优点

  • Promise最大的好处是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了。
promise.png
  • 解决回调地狱(Callback Hell)问题

Promise还可以做更多的事情,比如,有若干个异步任务,需要先做任务1,如果成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。

要串行执行这样的异步任务,不用Promise需要写一层一层的嵌套代码。有了Promise,我们只需要简单地写:

job1.then(job2).then(job3).catch(handleError);

其中,job1、job2和job3都是Promise对象。

  • Promise.all()并行执行异步任务

  • Promise.race()获得先返回的结果即可

eg.同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可。

Promise如何解决这两个问题

  • 解决可读性的问题

这一点不用多说,用过Promise的人很容易明白。Promise的应用相当于给了你一张可以把解题思路清晰记录下来的草稿纸,你不在需要用脑子去记忆执行顺序。

  • 解决信任问题

Promise并没有取消控制反转,而是把反转出去的控制再反转一次,也就是反转了控制反转。

这种机制有点像事件的触发。它与普通的回调的方式的区别在于,普通的方式,回调成功之后的操作直接写在了回调函数里面,而这些操作的调用由第三方控制。在Promise的方式中,回调只负责成功之后的通知,而回调成功之后的操作放在了then的回调里面,由Promise精确控制。

Promise有这些特征:只能决议一次,决议值只能有一个,决议之后无法改变。任何then中的回调也只会被调用一次。Promise的特征保证了Promise可以解决信任问题。

对于回调过早的问题,由于Promise只能是异步的,所以不会出现异步的同步调用。即便是在决议之前的错误,也是异步的,并不是会产生同步(调用过早)的困扰。

let a = new Promise((resolve, reject) => {
  let b = 1 + c;  // ReferenceError: c is not defined,错误会在下面的a打印出来之后报出。
  resolve(true);
})
console.log(1, a);
a.then(res => {
  console.log(2, res);
})
.catch(err => {
  console.log(err);
})

对于回调过晚或没有调用的问题,Promise本身不会回调过晚,只要决议了,它就会按照规定运行。至于服务器或者网络的问题,并不是Promise能解决的,一般这种情况会使用Promise的竞态APIPromise.race加一个超时的时间:

function timeoutPromise(delay) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      reject("Timeout!");
    }, delay);
  });
}

Promise.race([doSomething(), timeoutPromise(3000)])
.then(...)
.catch(...);

对于回调次数太少或太多的问题,由于Promise只能被决议一次,且决议之后无法改变,所以,即便是多次回调,也不会影响结果,决议之后的调用都会被忽略。


经典前端面试题每日更新,欢迎参与讨论,地址:https://github.com/daily-interview/fe-interview


更多angular1/2/4/5、ionic1/2/3、react、vue、微信小程序、nodejs等技术文章、视频教程和开源项目,请关注微信公众号——全栈弄潮儿

image

相关文章

  • 什么是Promise,它到底解决了什么问题?

    什么是Promise Promise 是异步编程的一种解决方案 Promise 核心 Promise 概括来说是对...

  • Javascript: Promise 学习笔记(1)

    什么是 Promise ? Promise 解决了什么问题? 语法 一、什么是 Promise ? A Promi...

  • Promise

    什么是Promise Promise解决了什么问题 Promise/A+规范 Promise的原理(如何实现链式调...

  • 全球超1300种虚拟货币,谁最有潜力呢?

    数字货币存在的意义? 数字货币作为一种解决方案,它到底要解决什么问题?它到底能解决什么问题? 如果它不能解决问题,...

  • promise解决了什么问题

    promise到底是做什么的?Promise是异步编程的一种解决方案 什么时候回来处理异步事件? (1)网络请求。...

  • Promise

    1.es6为什么会出现promise/解决了什么问题 2.promise的使用场景 3.promise的使用方法 ...

  • ES6 promise——初探

    本文思路 什么是异步 ES5异步实现方案 ES6 promise解决了什么问题 promise应该如何使用 1.异...

  • 煮 Retrofit 论 RxJava(二)

    为什么要用Rxjava?没看出Rxjava到底解决了我们什么问题。一门技术或框架只有解决了实际问题,我们才能体会它...

  • Promise 基础用法

    Promise ,为什么会出现它,Promise 的出现,解决了哪些问题呢? 解决了回调地狱(嵌套)的问题,不会导...

  • ThreadLocal到底是什么?它解决了什么问题?

    欢迎关注专栏:Java架构技术进阶。里面有大量batj面试题集锦,还有各种技术分享,如有好文章也欢迎投稿哦。 功能...

网友评论

    本文标题:什么是Promise,它到底解决了什么问题?

    本文链接:https://www.haomeiwen.com/subject/listectx.html