深入理解Promise并写一个符合Promise a+规范的Promise代码

Posted 另一种失败

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解Promise并写一个符合Promise a+规范的Promise代码相关的知识,希望对你有一定的参考价值。

  关于Promise函数可以参考我写的这篇文章https://www.cnblogs.com/qiaohong/p/7705262.html,我们现在就深入理解一下这个函数。

  首先说下Promise方法,Promise方法中还是有些是比较好用的,比如说Promise.all()方法(Promise.all()方法的参数是一个数组,会按照数组的结果放到成功的回调里,如果有一个错误那么就不会成功)、Promise.race()方法(这个方法的参数也是一个数组,Promise.race()会同时发起并发,但是以返回最快的结果为结果,可以用于多台服务器并发的时候用)。代码参考如下

  

let promise = new Promise()
let fs = require(\'mz/fs\');    //使用了一个mz的包  mz封装了fs对应的函数,并改为Promise
promise.race([fs.readFile(\'./name.txt\', \'utf8\'), fs.readFile(\'./age.txt\', \'utf8\')]).then((data) => {
  console.log(data);
}, err => {
  console.log(err);
});

  如何手写Promise a+规范的Promise呢?跟我一步步来,坐稳,看完了你也就懂了。

  先想Pormise的特点:  

  1.每次promise执行then后都会返回一个新的promise
  2.如果then中返回的是一个结果的话会把这个结果传递下一次then中的成功回调
  3.如果then中出现异常 会走下一个then的失败 将错误传递到失败中
  4.如果失败后还可以成功,如果返回undefined 会把undefined 传递给下一次
  5.catch 会捕获到没有捕获的异常
  6.成功或者失败是一个可选参数
  7. 如果then方法返回的是一个promise 那么会等待这个promise执行完决定返回的那个promise是成功还是失败
  8.为什么要返回一个新的promise而不是this promise状态确定后 就是不能更改。

 

  说干就干,拿起键盘就是怼

  

function Promise(executor) {
  let self = this;
  self.status = \'pending\';  //promise默认就是等待状态
  self.value = undefined;   //存放成功回调的值
  self.reason = undefined;  //存放失败回调的值
self.onResolved
= [];  //专门存放成功的回调函数 self.onRejected = [];  //存放失败的回调函数
function resolve(value) {  //promise成功走这个函数 if (self.status === \'pending\') { self.value = value; self.status = \'resolved\'; self.onResolved.forEach(fn => fn()); } } function reject(reason) {  //promise失败走这个函数 if (self.status === \'pending\') { self.reason = reason; self.status = \'rejected\'; self.onRejected.forEach(fn => fn()); } } try { executor(resolve, reject); } catch (e) { reject(e); } } //确定then里面的成功/失败函数执行的结果和返回的promise2是什么关系 //ps:promise a+里面确实有很多的槽点 比如这个x、y和promise2什么的都是那里面规定的 function resolvePromise(promise2, x, resolve, reject) { if (promise2 === x) { return reject(new TypeError(\'循环引用\')); } let called; if (x != null && (typeof x === \'object\' || typeof x === \'function\')) { try { let then = x.then; // 如何判断是promise 就判断又没then方法 if (typeof then === \'function\') { then.call(x, (y) => { if (called) return; called = true; resolvePromise(promise2, y, resolve, reject); }, (e) => { if (called) return; called = true; reject(e); }); } else { resolve(x); } } catch (e) { if (called) return; called = true; reject(e); } } else { resolve(x); } }
//promise的then方法 Promise.prototype.then
= function (onfulfilled, onrejected) { onfulfilled = typeof onfulfilled == \'function\' ? onfulfilled : val => val; onrejected = typeof onrejected === \'function\' ? onrejected : err => { throw err; } let self = this; let promise2;  //返回新的promise就是promise2 不要问我为什么 a+里面规范的 promise2 = new Promise((resolve, reject) => { if (self.status === \'resolved\') { setTimeout(() => { // 目的是为了实现异步 try { let x = onfulfilled(self.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }, 0); } if (self.status === \'rejected\') { setTimeout(() => { try { let x = onrejected(self.reason); resolvePromise(promise2, x, resolve, reject); // 解析x 和 promise2的关系 } catch (e) { reject(e); } }, 0); } if (self.status === \'pending\') { self.onResolved.push(function () { setTimeout(() => { try { let x = onfulfilled(self.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }, 0); }); self.onRejected.push(function () { setTimeout(() => { try { let x = onrejected(self.reason); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); } }, 0); }); } }) return promise2; }
//实现promise原生方法 Promise.all
= function (promises) { return new Promise((resolve, reject) => { let results = [];
   let i = 0; function processData(index, data) { results[index] = data; // let arr = [] arr[2] = 100 if (++i === promises.length) { resolve(results); } } for (let i = 0; i < promises.length; i++) { let p = promises[i]; p.then((data) => { // 成功后把结果和当前索引 关联起来 processData(i, data); }, reject); } }) } Promise.race = function (promises) { return new Promise((resolve, reject) => { for (let i = 0; i < promises.length; i++) { let p = promises[i]; p.then(resolve, reject); } }) } Promise.prototype.catch = function (onrejected) { return this.then(null, onrejected) } Promise.reject = function (reason) { return new Promise((resolve, reject) => { reject(reason) }) } Promise.resolve = function (value) { return new Promise((resolve, reject) => { resolve(value); }) }

 // 测试代码是否符合a+ 规范 为了让其能测试
 // npm install promises-aplus-tests -g
 // promises-aplus-tests 文件名 可以测试

Promise.defer = Promise.deferred = function () {
  let dfd = {};
  dfd.promise = new Promise((resolve, reject) => {
    dfd.resolve = resolve;
    dfd.reject = reject;
  });
  return dfd;
}
module.exports = Promise

  好了这就搞定了,大功告成。

  

以上是关于深入理解Promise并写一个符合Promise a+规范的Promise代码的主要内容,如果未能解决你的问题,请参考以下文章

手写Promise

Promise对象深入理解

深入理解 promise:promise的三种状态与链式调用

深入浅出理解Promise

深入理解ES6里的promise

JavaScript进阶深入理解JavaScript中ES6的Promise的作用并实现一个自己的Promise