html5 promise,特皮团队:一年菜鸟实现Promise所有方法

从零手写Promise完整版随着前端技术的不断发展,用户对界面的要求也在不断提高,现在的前端不再是之前的html+css, 而是html+css+js,但是想学好js首先要知道js的核心在于异步,说到异步大部分人第一时间会想到Promise。

那么接下来我们就来学习一下Promise是如何实现的吧。

首先我们回顾一下Promise的基本使用const p = new Promise((resolve,reject)=>{

resolve('返回成功的值')

reject('返回失败的值')

})

p.then(value=>{

console.log(value) // 返回成功的值

})new Promise构造函数内的回调数是同步执行的

then的回调函数,是异步执行的

调用resolve/reject后,状态已定,状态不能再改变

.then每次返回的都是新的Promise

Promise可以嵌套

接着我们从零开始来实现一下Promise先来实现明确一下基本的结构(function(window){

// 定义MyPromise构造函数

function MyPromise(executor){

function resolve(value){

}

function reject(reason){

}

executor(resolve,reject)

}

// MyPromise原型链上存在then方法

MyPromise.prototype.then = function(onResolved,onRejected){

}

//MyPromise原型链上存在catch方法

MyPromise.prototype.catch = function(onRejected){

}

//MyPromise实例对象上存在resolve方法

MyPromise.resolve = function(value){

}

//MyPromise实例对象上存在reject方法

MyPromise.reject = function(reason){

}

//MyPromise实例对象上存在all方法

MyPromise.all = function(promises){

}

//MyPromise实例对象上存在race方法

MyPromise.race = function(promises){

}

window.MyPromise = MyPromise;

})(window)明确来了基本的结构后,接下里我们来看看MyPromise构造函数内需要做什么

1.定义Promise的初始状态、初始值、存放待执行异步函数的数组(function(window){

const PENDDING = 'pendding';

const FULFILLED = 'fulfilled';

const REJECTED = 'rejected';

function MyPromise(executor){

const self = this;

self.status = PENDDING; //初始状态

self.data = undefined; // 初始值

self.callbacks = []; // 待执行异步回调函数的数组

function resolve(value){

}

function reject(reason){

}

executor(resolve,reject)

}

window.MyPromise = MyPromise;

})(window)根据Promise状态的不同,进行修,赋值,以及立即执行异步回调(function (window) {

const PENDDING = 'pendding';

const FULFILLED = 'fulfilled';

const REJECTED = 'rejected';

// 定义MyPromise

function MyPromise(executor) {

const self = this;

self.status = PENDDING;

self.data = undefined;

self.callbacks = [];

function resolve(value) {

self.status = FULFILLED;

self.data = value;

// 立即执行异步回调函数

setTimeout(() => {

self.callbacks.forEach(callbacksObj => {

callbacksObj.onResolved(value);

})

})

}

function reject(reason) {

self.status = REJECTED;

self.data = reason;

setTimeout(() => {

self.callbacks.forEach(callbacksObj => {

callbacksObj.onRejected(reason);

})

})

}

executor(resolve, reject)

}

window.MyPromise = MyPromise;别忘了Promise 的状态一旦改变就不能再修改了,所以在resolve/reject函数内需要加一个判断(function (window) {

const PENDDING = 'pendding';

const FULFILLED = 'fulfilled';

const REJECTED = 'rejected';

// 定义MyPromise

function MyPromise(executor) {

const self = this;

self.status = PENDDING;

self.data = undefined;

self.callbacks = [];

function resolve(value) {

if (self.status !== PENDDING) return;

self.status = FULFILLED;

self.data = value;

// 立即执行异步回调函数

setTimeout(() => {

self.callbacks.forEach(callbacksObj => {

callbacksObj.onResolved(value);

})

})

}

function reject(reason) {

if (self.status !== PENDDING) return;

self.status = REJECTED;

self.data = reason;

setTimeout(() => {

self.callbacks.forEach(callbacksObj => {

callbacksObj.onRejected(reason);

})

})

}

executor(resolve, reject)

}

window.MyPromise = MyPromise;Promise原型链上的then方法,可以接收两个参数(且是回调函数),成功/失败,并且每次返回的都是一个新的Promise// MyPromise原型链上存在then方法

MyPromise.prototype.then = function (onResolved, onRejected) {

const self = this;

return new MyPromise((resolve, reject) => { // 每次都返回一个新的Promise对象

// 首先判断当前状态

if (self.status === FULFILLED) {

/*

1、返回的Promise的结果是由onResolved/onrejected决定的

2、返回的是Promise对象 (根据执结果决定Promise的返回结果)

3、返回的不是Promise对象 (该值就是Promise的返回结果)

4、抛出异常 异常的值为返回的结果

*/

setTimeout(() => {

try {

const result = onResolved(self.data);

if (reject instanceof MyPromise) {

result.then(value => {

resolve(value);

}, reason => {

reject(reason);

})

} else {

resolve(result);

}

} catch (error) {

reject(error);

}

});

} else if (self.status === REJECTED) {

setTimeout(() => {

try {

const result = onRejected(self.data);

if (reject instanceof MyPromise) {

result.then(value => {

resolve(value);

}, reason => {

reject(reason);

})

} else {

resolve(result);

}

} catch (error) {

reject(error);

}

});

} else if (self.status === PENDDING) {

self.callbacks.push({

onResolved() {

try {

const result = onResolved(self.data);

if (reject instanceof MyPromise) {

result.then(value => {

resolve(value);

}, reason => {

reject(reason);

})

} else {

resolve(result);

}

} catch (error) {

reject(error);

}

},

onRejected() {

try {

const result = onRejected(self.data);

if (reject instanceof MyPromise) {

result.then(value => {

resolve(value);

}, reason => {

reject(reason);

})

} else {

resolve(result);

}

} catch (error) {

reject(error);

}

}

})

}

})

}好的停一下,一步一步讲解

.then每次都返回一个新的Promise,所以在.then方法里是

> return new MyPromise((resolve,reject)){}每一种状态都存在返回值,并且都能是一下三种情况

返回的是Promise对象

返回的不是Promise对象

抛出异常

FULFILLED/REJECTED两种状态需要立即执行异步函数

PENDDING为什么没有立即执行异步函数,因为当状态为PENDDING时就执行then,会先往待执行回调函数的数组(callbacks)内存放这个回调,紧接着在回到Promise的执行其中执行resolve/reject,而上面也写过了,执行resolve/reject会去待执行回调函数的数组内遍历并赋值。

ee7e19ca9703b7a54fd8bcd62dd62632.png好的继续,并且对上面重复的优化一下。// MyPromise原型链上存在then方法

MyPromise.prototype.then = function (onResolved, onRejected) {

const self = this;

return new MyPromise((resolve, reject) => { // 每次都返回一个新的Promise对象

function handle(callback) {

/*

1、返回的Promise的结果是由onResolved/onrejected决定的

2、返回的是Promise对象 (根据执结果决定Promise的返回结果)

3、返回的不是Promise对象 (该值就是Promise的返回结果)

4、抛出异常 异常的值为返回的结果

*/

try {

const result = callback(self.data);

if (reject instanceof MyPromise) {

result.then(value => {

resolve(value);

}, reason => {

reject(reason);

})

} else {

resolve(result);

}

} catch (error) {

reject(error);

}

}

// 首先判断当前状态

if (self.status === FULFILLED) {

setTimeout(() => {

thandle(onResolved)

});

} else if (self.status === REJECTED) {

setTimeout(() => {

thandle(onRejected)

});

} else if (self.status === PENDDING) {

self.callbacks.push({

onResolved() {

handle(onResolved)

},

onRejected() {

handle(onRejected)

}

})

}

})

}防止不穿成功或者失败的回调函数,给成功和失败都给一个默认回调函数MyPromise.prototype.then = function (onResolved, onRejected) {

const self = this;

// 定义默认回调

onResolved = typeof onResolved === "function" ? onResolved : value => value;

onRejected = typeof onRejected === "function" ? onRejected : reason => {throw reason};

return new MyPromise((resolve, reject) => { // 每次都返回一个新的Promise对象

function handle(callback) {

/*

1、返回的Promise的结果是由onResolved/onrejected决定的

2、返回的是Promise对象 (根据执结果决定Promise的返回结果)

3、返回的不是Promise对象 (该值就是Promise的返回结果)

4、抛出异常 异常的值为返回的结果

*/

try {

const result = callback(self.data);

if (reject instanceof MyPromise) {

result.then(value => {

resolve(value);

}, reason => {

reject(reason);

})

} else {

resolve(result);

}

} catch (error) {

reject(error);

}

}

// 首先判断当前状态

if (self.status === FULFILLED) {

setTimeout(() => {

thandle(onResolved)

});

} else if (self.status === REJECTED) {

setTimeout(() => {

thandle(onRejected)

});

} else if (self.status === PENDDING) {

self.callbacks.push({

onResolved() {

handle(onResolved)

},

onRejected() {

handle(onRejected)

}

})

}

})

}接着我们看看catch,其实就是Promise.prototype.then(undefined,rejected)或者Promise.prototype.then(null,rejected)//MyPromise原型链上存在catch方法

MyPromise.prototype.catch = function (onRejected) {

return this.then(null, onRejected);

}7、接下来实现一下 Promise.resolve/Promise.reject/MyPromise实例对象上存在resolve方法

MyPromise.resolve = function (value) {

if (value instanceof MyPromise) return value;

return new MyPromise(resolve => resolve(value)) // 返回一个resolved状态的Promise对象

}

//MyPromise实例对象上存在reject方法

MyPromise.reject = function (reason) {

return new MyPromise((resolve,reject) => reject(reason)); // 返回一个reject状态Promise对象

}接下来实现一下Promise.all/Promise.race//MyPromise实例对象上存在all方法

MyPromise.all = function (promises) {

let promisesCount = 0

let values = new Array(promises.length);

return new MyPromise((resolve,reject)=>{

promises.forEach((promise,index)=>{

promise.then(value => {

promisesCount++;

values[index] = value;

if (promisesCount === promises.length){

resolve(values);

}

},reason => {

reject(reason);

})

})

})

}好的,我们来看看Promise.all实现的思路Promise.all 传入的是一个数组

Promise.all返回的是一个数组

Promise.all传入的数组中,每个Promise对象必须都正确才能返回正确的结果数组

Promise.all传入的数组中任意一个对象返回错的结果,都会返回错误的结果

好的,其实我们还少一个步骤就是Promise.all传入的数组的参数可以不是Promise的实例, 所以数组参数如果不是Promise实例,先调用Promise.resolve//MyPromise实例对象上存在all方法

MyPromise.all = function (promises) {

let promisesCount = 0

let values = new Array(promises.length);

return new MyPromise((resolve, reject) => {

promises.forEach((promise, index) => {

MyPromise.resolve(promise).then(value => {

promisesCount++;

values[index] = value;

if (promisesCount === promises.length) {

resolve(values);

}

}, reason => {

reject(reason);

})

})

})

}Promise.race实现//MyPromise实例对象上存在race方法

MyPromise.race = function (promises) {

return new MyPromise((resolve, reject) => {

promises.forEach(promise => {

MyPromise.resolve(promise).then(value => {

resolve(value);

}, reason => {

reject(reason)

})

})

})

}

好的,解释一下,Promise.race传入的也是一个数组

传入的Promise执行内容相同的情况下,Promise.race返回的结果为数组中的第一个值

若传入的Promise执行内容不一致,有先后区分,则结果为执行的最快的一个至此从零手写一个Promise完成了,其中包括Promise.prototype.then

Promise.prototype.catch

Promise.resolve

Promise.reject

Promise.all

Promise.race(function (window) {

const PENDDING = 'pendding';

const FULFILLED = 'fulfilled';

const REJECTED = 'rejected';

// 定义MyPromise

function MyPromise(executor) {

const self = this;

self.status = PENDDING;

self.data = undefined;

self.callbacks = [];

function resolve(value) {

if (self.status !== PENDDING) return;

self.status = FULFILLED;

self.data = value;

// 立即执行异步回调函数

setTimeout(() => {

self.callbacks.forEach(callbacksObj => {

callbacksObj.onResolved(value);

})

})

}

function reject(reason) {

if (self.status !== PENDDING) return;

self.status = REJECTED;

self.data = reason;

setTimeout(() => {

self.callbacks.forEach(callbacksObj => {

callbacksObj.onRejected(reason);

})

})

}

try{

executor(resolve, reject)

}catch(error){

reject(error)

}

}

// MyPromise原型链上存在then方法

MyPromise.prototype.then = function (onResolved, onRejected) {

const self = this;

// 定义默认回调

onResolved = typeof onResolved === "function" ? onResolved : value => value;

onRejected = typeof onRejected === "function" ? onRejected : reason => {

throw reason

};

return new MyPromise((resolve, reject) => { // 每次都返回一个新的Promise对象

function handle(callback) {

/*

1、返回的Promise的结果是由onResolved/onrejected决定的

2、返回的是Promise对象 (根据执结果决定Promise的返回结果)

3、返回的不是Promise对象 (该值就是Promise的返回结果)

4、抛出异常 异常的值为返回的结果

*/

try {

const result = callback(self.data);

if (reject instanceof MyPromise) {

result.then(value => {

resolve(value);

}, reason => {

reject(reason);

})

} else {

resolve(result);

}

} catch (error) {

reject(error);

}

}

// 首先判断当前状态

if (self.status === FULFILLED) {

setTimeout(() => {

handle(onResolved)

});

} else if (self.status === REJECTED) {

setTimeout(() => {

handle(onRejected)

});

} else if (self.status === PENDDING) {

self.callbacks.push({

onResolved() {

handle(onResolved)

},

onRejected() {

handle(onRejected)

}

})

}

})

}

//MyPromise原型链上存在catch方法

MyPromise.prototype.catch = function (onRejected) {

return this.then(null, onRejected);

}

//MyPromise实例对象上存在resolve方法

MyPromise.resolve = function (value) {

if (value instanceof MyPromise) return value;

return new MyPromise(resolve => resolve(value)) // 返回一个resolved状态的Promise对象

}

//MyPromise实例对象上存在reject方法

MyPromise.reject = function (reason) {

return new MyPromise((resolve, reject) => reject(reason)); // 返回一个reject状态Promise对象

}

//MyPromise实例对象上存在all方法

MyPromise.all = function (promises) {

let promisesCount = 0

let values = new Array(promises.length);

return new MyPromise((resolve, reject) => {

promises.forEach((promise, index) => {

MyPromise.resolve(promise).then(value => {

promisesCount++;

values[index] = value;

if (promisesCount === promises.length) {

resolve(values);

}

}, reason => {

reject(reason);

})

})

})

}

//MyPromise实例对象上存在race方法

MyPromise.race = function (promises) {

return new MyPromise((resolve, reject) => {

promises.forEach(promise => {

MyPromise.resolve(promise).then(value => {

resolve(value);

}, reason => {

reject(reason)

})

})

})

}

window.MyPromise = MyPromise;

})(window)最后我们用类(class)的方式实现一下(function (window) {

const PENDDING = 'pendding';

const FULFILLED = 'fulfilled';

const REJECTED = 'rejected';

// 定义MyPromise

class MyPromise {

constructor(executor) {

const self = this;

self.status = PENDDING;

self.data = undefined;

self.callbacks = [];

function resolve(value) {

if (self.status !== PENDDING) return;

self.status = FULFILLED;

self.data = value;

// 立即执行异步回调函数

setTimeout(() => {

self.callbacks.forEach(callbacksObj => {

callbacksObj.onResolved(value);

})

})

}

function reject(reason) {

if (self.status !== PENDDING) return;

self.status = REJECTED;

self.data = reason;

setTimeout(() => {

self.callbacks.forEach(callbacksObj => {

callbacksObj.onRejected(reason);

})

})

}

executor(resolve, reject)

}

// MyPromise原型链上存在then方法

then(onResolved, onRejected) {

const self = this;

// 定义默认回调

onResolved = typeof onResolved === "function" ? onResolved : value => value;

onRejected = typeof onRejected === "function" ? onRejected : reason => {

throw reason

};

return new MyPromise((resolve, reject) => { // 每次都返回一个新的Promise对象

function handle(callback) {

/*

1、返回的Promise的结果是由onResolved/onrejected决定的

2、返回的是Promise对象 (根据执结果决定Promise的返回结果)

3、返回的不是Promise对象 (该值就是Promise的返回结果)

4、抛出异常 异常的值为返回的结果

*/

try {

const result = callback(self.data);

if (reject instanceof MyPromise) {

result.then(value => {

resolve(value);

}, reason => {

reject(reason);

})

} else {

resolve(result);

}

} catch (error) {

reject(error);

}

}

// 首先判断当前状态

if (self.status === FULFILLED) {

setTimeout(() => {

handle(onResolved)

});

} else if (self.status === REJECTED) {

setTimeout(() => {

handle(onRejected)

});

} else if (self.status === PENDDING) {

self.callbacks.push({

onResolved() {

handle(onResolved)

},

onRejected() {

handle(onRejected)

}

})

}

})

}

//MyPromise原型链上存在catch方法

catch (onRejected) {

return this.then(null, onRejected);

}

//MyPromise实例对象上存在resolve方法

static resolve(value) {

if (value instanceof MyPromise) return value;

return new MyPromise(resolve => resolve(value)) // 返回一个resolved状态的Promise对象

}

//MyPromise实例对象上存在reject方法

static reject(reason) {

return new MyPromise((resolve, reject) => reject(reason)); // 返回一个reject状态Promise对象

}

//MyPromise实例对象上存在all方法

static all(promises) {

let promisesCount = 0

let values = new Array(promises.length);

return new MyPromise((resolve, reject) => {

promises.forEach((promise, index) => {

MyPromise.resolve(promise).then(value => {

promisesCount++;

values[index] = value;

if (promisesCount === promises.length) {

resolve(values);

}

}, reason => {

reject(reason);

})

})

})

}

//MyPromise实例对象上存在race方法

static race(promises) {

return new MyPromise((resolve, reject) => {

promises.forEach(promise => {

MyPromise.resolve(promise).then(value => {

resolve(value);

}, reason => {

reject(reason)

})

})

})

}

}

window.MyPromise = MyPromise;

})(window)从零手写Promise说难也不难,但是还是花了不少时间的,希望能够帮助到像我一样想学好js,想学好Promise的朋友,一起加油吧。

最后如果你想加入特皮技术团队,有人指导你学习,提升自己,可以公众号联系我

感觉对你有帮助,可以点个在看和赞,转发一下,关注我们公众号:【前端巅峰】

b739ec46bb5c46d9c0aa4ce35ba1ea56.png

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[特皮团队:一年菜鸟实现Promise所有方法]http://www.zyiz.net/tech/detail-146118.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值