Promise问答

本文主要针对这篇文章提出的问题,做个解答。

1.了解 Promise 吗?

  Promise是一种异步编程的解决方案,有三种状态,pending(进行中)、resolved(已完成)、rejected(已失败)。当Promise的状态由pending转变为resolved或reject时,会执行相应的方法。

  特点:

  1、只有异步操作的结果,可以决定当前是哪一种状态,任务其他操作都无法改变这个状态,也是“Promise”的名称的由来。

  2、状态一旦改变,就无法再次改变状态。

2.Promise 解决的痛点是什么?

  1、回调地狱带来的负面作用:代码臃肿,可读性差,只能在回调里处理异常。。

  2、事件,事件的特点是如果你错过了它,再去监听,是得不到结果的。而Promise如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。

3.Promise 解决的痛点还有其他方法可以解决吗?如果有,请列举。

  setTimeout、事件监听、回调函数、Generator函数,async/await

  1、setTimeout:缺点不精确,只是确保在一定时间后加入到任务队列,并不保证立马执行。只有执行引擎栈中的代码执行完毕,主线程才会去读取任务队列。

  2、事件监听:任务的执行不取决于代码的顺序,而取决于某个事件是否发生。 

  3、Generator函数虽然将异步操作表示得很简洁,但是流程管理却不方便(即何时执行第一阶段、何时执行第二阶段)。即如何实现自动化的流程管理。

  4、async/await

4.Promise如何使用

  1、创建实例

//创造一个Promise实例。
const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

//Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

  2、可用Promise的try和catch方法预防异常

Promise.try(database.users.get({id: userId}))
  .then(...)
  .catch(...)

5.Promise 常用的方法,方法的作用?

  1、Promise.prototype.then()、Promise.prototype.catch()、Promise.prototype.finally()、Promise.all()、Promise.race()、Promise.resolve()、Promise.reject()。

  2、Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

  //只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled。

  3、Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.race([p1, p2, p3]);

  //只有p1、p2、p3有一个实例率先改变状态,p的状态就跟着改变。

  //下面是一个例子,如何指定时间内没有获取结果,就将promise的状态变为reject,否则变为resolve。

const p = Promise.race([
  fetch('/resource-that-may-take-a-while'),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
]);

p
.then(console.log)
.catch(console.error);

6.Promise 在事件循环中的执行过程是怎样的?

  首先什么是事件循环?看下这篇文章,https://www.cnblogs.com/xiaohuochai/p/8527618.html。简要提取下就是:

   从代码执行顺序的角度来看,程序最开始是按代码顺序执行代码的,遇到同步任务,立刻执行;遇到异步任务,则只是调用异步函数发起异步请求。此时,异步任务开始执行异步操作,执行完成后到消息队列中排队。程序按照代码顺序执行完毕后,查询消息队列中是否有等待的消息。如果有,则按照次序从消息队列中把消息放到执行栈中执行。执行完毕后,再从消息队列中获取消息,再执行,不断重复。

  由于主线程不断的重复获得消息、执行消息、再取消息、再执行。所以,这种机制被称为事件循环

   promise的构造部分是同步执行,script(主程序代码)—>process.nextTick—>Promises...——>setTimeout——>setInterval——>setImmediate——> I/O——>UI rendering。引用文章:https://github.com/forthealllight/blog/issues/5

setTimeout(function(){console.log(1)},0);

new Promise(function(resolve,reject){
   console.log(2);
   resolve();
}).then(function(){console.log(3)
}).then(function(){console.log(4)});

process.nextTick(function(){console.log(5)});

console.log(6);

//输出2,6,5,3,4,1

7.能不能手写一个 Promise 的 polyfill

  https://github.com/stefanpenner/es6-promise

 

posted @ 2018-07-16 14:58  简惬  阅读(393)  评论(0编辑  收藏  举报