- let p = new Promise((resolve, reject) => {
- //支持异步操作
- setTimeout(function(){
- resolve('success')
- },1000);
- //resolve('success')
- // reject('error')
- })
- p.then(data => {
- console.log(data)
- return data;
- }).then(data=>{
- console.log(data);
- })
- class MPromise {
- constructor(callback) {
- // 执行回调函数
- callback();
- }
- }
- class MPromise {
- constructor(callback) {
- // 定义成功返回参数。为什在构造器里面定义?
- this.value = undefined;
-
- // 定义失败返回参数
- this.reason = undefined;
-
- // 定义两个处理函数
- const resolve = (value) => {
- this.value = value;
- console.log(this.value);
- }
-
- const reject = (reason) => {
- this.reason = reason;
- }
-
- // 执行回调函数
- callback(resolve,reject);
- }
- }
-
- // MPromise类调用
- let p = new MPromise((resolve,reject)=>{
- resolve("success");
- });
定义promise的初始状态pending(后面两个状态在执行对应函数resolve和reject后进行更改)
实现then方法:传入
- class MPromise {
- constructor(callback) {
- // 定义成功返回参数。为什在构造器里面定义?
- this.value = undefined;
- // 定义失败返回参数
- this.reason = undefined;
-
- // 定义promise的初始状态pending(后面两个状态在执行对应函数后进行更改)
- this.state = 'pending';
-
- // 定义两个处理函数
- const resolve = (value) => {
- this.value = value;
- if(this.state === 'pending'){
- this.state = 'fulfilled';
- }
- }
-
- const reject = (reason) => {
- this.reason = reason;
- if(this.state === 'pending'){
- this.state = 'rejected';
- }
- }
-
- // 执行回调函数
- callback(resolve,reject);
- }
- // then方法时MPromise创建的实例调用的所以在constructor外
- // then()方法会接受两个函数参数(onFulfilled和onRejected)
- then(onFulfilled,onRejected){
- // 容错:onFulfilled,onRejected存在且为function时才能进行调用
- let onFulfilledState = onFulfilled ? typeof onFulfilled === 'function' : true; //判断如果onFulfilled传入了则继续判断是否为function函数,否则直接返回true传入什么返回什么
- let onRejectedState = onRejected ? typeof onRejected === 'function' : true;
- if(onFulfilledState && onRejectedState){
- // 根据对应状态调用不同的处理函数
- if(this.state === 'fulfilled'){
- onFulfilled(this.value);
- }
-
- if(this.state === 'rejected'){
- onRejected(this.value);
- }
- }
- }
- }
-
- // MPromise类调用
- let p = new MPromise((resolve,reject)=>{
- resolve("success");
- });
- p.then((data)=>{
- console.log(data);
- });
以上代码,如果加入定时器实现异步就会发现打印不了
- // MPromise类调用
- let p = new MPromise((resolve,reject)=>{
- setTimeout(function (){
- resolve("success");
- },1000)
- });
- p.then((data)=>{
- console.log(data);
- });
给then方法加入返回值 new MPromise发现还是没有返回
- then(onFulfilled, onRejected) {
- return new MPromise((resolve, reject) => {
- // 容错:onFulfilled,onRejected存在且为function时才能进行调用
- let onFulfilledState = onFulfilled ? typeof onFulfilled === 'function' : true; //判断如果onFulfilled传入了则继续判断是否为function函数,否则直接返回true传入什么返回什么
- let onRejectedState = onRejected ? typeof onRejected === 'function' : true;
- if (onFulfilledState && onRejectedState) {
-
- // 根据对应状态调用不同的处理函数
- if (this.state === 'fulfilled') {
- resolve(onFulfilled(this.value));
- }
-
- if (this.state === 'rejected') {
- reject(onRejected(this.value));
- }
- }
- });
- }
为什么加入了new MPromise()后还是没有返回?因为这里是通过setTimeout()进行异步操作,当执行then方法时,回调函数中的resolve()并未执行完成,就会导致状态一直是pending
分析:发现p.then方法里面的函数不会触发,setTimeout()里面的resolve也没有执行
为什么加入了new MPromise()后还是没有返回?因为new MPromise()时,发现setTimeout()定时任务就会将其放到异步队列里面,而通过p.then()调用方法时,回调函数中的resolve()并未执行完成,this.state状态一直处于pending状态,自然也就没有调用resolve(onFulfilled())方法
解决思路:(观察者模式)
既然 then 自己无法知道 resolve 什么时候执行,是否执行了,那resolve执行完后就需要有个东西告诉then,执行完了。
即在then里面判断为pending状态时,将成功和失败的方法分别记录到一个数组里面,然后再分别再resolve()和reject()触发时,再去遍历执行数组存进去的函数
关键代码:
- // 设置数组用于存放异步队列中所有的resolve和reject函数
- this.onResolveCallback = [];
- this.onRejectCallback = [];
-
- // 定义两个处理函数
- const resolve = (value) => {
- this.value = value;
- if (this.state === 'pending') {
- this.state = 'fulfilled';
- }
- if (this.state === 'fulfilled') {
- this.onResolveCallback.forEach(resolveCb => resolveCb(this.value));
- }
- }
-
- const reject = (reason) => {
- this.reason = reason;
- if (this.state === 'pending') {
- this.state = 'rejected';
- }
- if (this.state === 'rejected') {
- this.onRejectCallback.forEach(rejectCb => rejectCb(this.reason));
- }
- }
- .......
- // 当异步执行时,状态会一直为pending
- if(this.state === 'pending') {
-
- this.onResolveCallback.push(() => {
- onFulfilled(this.value)
- })
- this.onRejectCallback.push(() => {
- onRejected(this.reason)
- })
- }
完整代码:
- class MPromise {
- constructor(callback) {
- // 定义成功返回参数。为什在构造器里面定义?
- this.value = undefined;
- // 定义失败返回参数
- this.reason = undefined;
-
- // 定义promise的初始状态pending(后面两个状态在执行对应函数后进行更改)
- this.state = 'pending';
-
- // 设置数组用于存放异步队列中所有的resolve和reject函数
- this.onResolveCallback = [];
- this.onRejectCallback = [];
-
- // 定义两个处理函数
- const resolve = (value) => {
- this.value = value;
- if (this.state === 'pending') {
- this.state = 'fulfilled';
- }
- if (this.state === 'fulfilled') {
- this.onResolveCallback.forEach(resolveCb => resolveCb(this.value));
- }
- }
-
- const reject = (reason) => {
- this.reason = reason;
- if (this.state === 'pending') {
- this.state = 'rejected';
- }
- if (this.state === 'rejected') {
- this.onRejectCallback.forEach(rejectCb => rejectCb(this.reason));
- }
- }
-
- // 执行回调函数
- callback(resolve, reject);
- }
- // then方法时MPromise创建的实例调用的所以在constructor外
- // then()方法会接受两个函数参数(onFulfilled和onRejected)
- then(onFulfilled, onRejected) {
- return new MPromise((resolve, reject) => {
- // 容错:onFulfilled,onRejected存在且为function时才能进行调用
- let onFulfilledState = onFulfilled ? typeof onFulfilled === 'function' : true; //判断如果onFulfilled传入了则继续判断是否为function函数,否则直接返回true传入什么返回什么
- let onRejectedState = onRejected ? typeof onRejected === 'function' : true;
- if (onFulfilledState && onRejectedState) {
-
- // 根据对应状态调用不同的处理函数
- if (this.state === 'fulfilled') {
- resolve(onFulfilled(this.value));
- }
-
- if (this.state === 'rejected') {
- reject(onRejected(this.value));
- }
- // 当异步执行时,状态会一直为pending
- if (this.state === 'pending') {
- // push进去的是下一次resolve函数
-
- this.onResolveCallback.push(()=>onFulfilled(this.value));
- this.onRejectCallback.push(()=>onRejected(this.reason));
- }
- }
- });
- }
- }
-
- // MPromise类调用
- let p = new MPromise((resolve, reject) => {
- setTimeout(function () {
- resolve("success");
- // reject("error");
- }, 1000)
- });
- p.then((data) => {
- console.log(data);
- return data
- },err=>{
- console.log(err);
- }).then((data)=>{
- console.log("第二次调用then",data);
-
- })
链式调用的本质是需要调用then方法后返回一个promise对象,且内部仍然会执行resolve和reject函数
特点:后面每个.then()方法中能获得上一个.then()返回的参数
解决:push进数组时再通过resolve方法执行就能重新通过then进行调用
- // 当异步执行时,状态会一直为pending
- if (this.state === 'pending') {
- this.onResolveCallback.push(()=>resolve(onFulfilled(this.value)));
- this.onRejectCallback.push(()=>resolve(onRejected(this.reason)));
- }
其实就是单独调用new MPromise里面的resolve方法
- // 其实就是单独调用new MPromise里面的resolve方法
- static resolve = (value) => new MPromise((resolve,reject)=>resolve(value));
- static reject = (reason) => new MPromise((resolve,reject)=>resolve(reason));
-
- MPromise.resolve("这是静态方法MPromise.resolve调用").then((data)=>{
- console.log(data);
- return data;
- }).then(data=>{
- console.log("第二次调用静态方法MPromise.resolve调用",data);
-
- })
- MPromise.reject("这是静态方法MPromise.reject调用").then((error)=>{
- console.log(error);
- })
MPromise.all() 关键是需要在循环中调用promise.then()方法向下执行,最后判断数组中所有promise执行完后,通过resolve返回结果
- static all = (promiseArr) => new MPromise((resolve, reject)=>{
- // 使用数组存放所有MPromise传入的参数数据
- let results = [];
- // 使用count记录处理的MPromise,每处理一个+1,直到最后一个处理完就返回参数数组
- let count = 0;
- promiseArr.forEach((promise,index)=>{
- promise.then(item=>{
- results[index] = item;
- count++;
- console.log(promise.value);
- // 注意此处用数组下标判断会出现问题:setTimeout()异步的会等results其他输出后第二次输出
- if(count === promiseArr.length){
- resolve(results);
- }
- });
-
- });
- })
-
- let p1 = new MPromise(1);
- let p2 = new MPromise((resolve, reject) => {
- setTimeout(function(){
- resolve("p2");
- }, 2000);
- })
- let p3 = new MPromise((resolve, reject) => {
- resolve("p3");
- })
- let p4 = new MPromise((resolve, reject) => {
- resolve("p4");
- })
-
- MPromise.all([p1, p2, p3, p4]).then(result => {
- console.log(result);
- });
手写promise中,Promise.all方法实现时,为什么不能使用index进行判断(异步时不会同时打印,等其他打印完再打印异步的)
使用index判断打印的结果为:p1,p3,p4。p2过一秒后才打印
- static all = (promiseArr) => new MPromise((resolve, reject)=>{
- // 使用数组存放所有MPromise传入的参数数据
- let results = [];
- // 使用count记录处理的MPromise,每处理一个+1,直到最后一个处理完就返回参数数组
- let count = 0;
- promiseArr.forEach((promise,index)=>{
- promise.then(item=>{
- results[index] = item;
- count++;
- console.log(promise.value);
- // 注意此处用数组下标判断会出现问题:setTimeout()异步的会等results其他输出后第二次输出
- if(count === promiseArr.length){
- resolve(results);
- }
- });
-
- });
- })
问题分析:
promise.then()被调用才能表示当前promise执行完,而index是在外层的,所以用index判断会输出有问题
- /*
- 实现功能:
- 有一个Promise构造函数,传入resolve和reject两个参数,是两个可以执行的函数
- promise有三种状态:pending等待,fulfilled成功,rejected失败
- 状态pending 一旦转为fulfilled或者rejected,不能再更改
- resolve()方法为成功处理方法,将状态由pending转为fulfilled,且传入参数value
- reject()方法为失败处理方法,将状态由pending转为rejected,且传入参数reason
- then()方法接受两个参数,分别为onFulfilled和onRejected函数,当状态由pending转为fulfilled后执行onFulfilled函数,由pending转为rejected后指向onRejected函数
- .then()方法支持链式调用,创建Promise实例后,可以通过实例一直调用.then()方法触发
- 静态方法的实现:Promise.resolve(),Promise.reject(),Promise.all()
- 基本步骤:
- 需要创建一个Promise类,并且添加一个回调方法 callback,作为Promise 的参数
- callback接收resolve 和 reject 作为参数
- 定义promise的三种状态,实现then方法
- then()方法可实现异步操作(用定时器进行测试)
- 实现链式调用
- 添加静态方法
- */
- // 问题:写在constructor里面的函数和写在constructor外的函数区别
- // constructor里面的函数,通过构造方法创建时就必须传入回调函数
- class MPromise {
- constructor(callback) {
- // 定义成功返回参数。为什在构造器里面定义?
- this.value = undefined;
- // 定义失败返回参数
- this.reason = undefined;
-
- // 定义promise的初始状态pending(后面两个状态在执行对应函数后进行更改)
- this.state = 'pending';
-
- // 设置数组用于存放异步队列中所有的resolve和reject函数
- this.onResolveCallback = [];
- this.onRejectCallback = [];
-
- // 定义两个处理函数
- const resolve = (value) => {
- this.value = value;
- if (this.state === 'pending') {
- this.state = 'fulfilled';
- }
- if (this.state === 'fulfilled') {
- this.onResolveCallback.forEach(resolveCb => resolveCb(this.value));
- }
- }
-
- const reject = (reason) => {
- this.reason = reason;
- if (this.state === 'pending') {
- this.state = 'rejected';
- }
- if (this.state === 'rejected') {
- this.onRejectCallback.forEach(rejectCb => rejectCb(this.reason));
- }
- }
-
- // 执行回调函数(对传入非function的进行处理)
- typeof callback === 'function'? callback(resolve, reject): resolve(callback);
- }
- // then方法时MPromise创建的实例调用的所以在constructor外
- // then()方法会接受两个函数参数(onFulfilled和onRejected)
- then(onFulfilled, onRejected) {
- return new MPromise((resolve, reject) => {
- // 容错:onFulfilled,onRejected存在且为function时才能进行调用
- let onFulfilledState = onFulfilled ? typeof onFulfilled === 'function' : true; //判断如果onFulfilled传入了则继续判断是否为function函数,否则直接返回true传入什么返回什么
- let onRejectedState = onRejected ? typeof onRejected === 'function' : true;
- if (onFulfilledState && onRejectedState) {
-
- // 根据对应状态调用不同的处理函数
- if (this.state === 'fulfilled') {
- resolve(onFulfilled(this.value));
- }
-
- if (this.state === 'rejected') {
- reject(onRejected(this.value));
- }
- // 当异步执行时,状态会一直为pending
- if (this.state === 'pending') {
- // push进去的是下一次resolve函数
- this.onResolveCallback.push(() => resolve(onFulfilled(this.value)));
- this.onRejectCallback.push(() => resolve(onRejected(this.reason)));
- }
- }
- });
- }
-
- // 其实就是单独调用new MPromise里面的resolve方法
- static resolve = (value) => new MPromise((resolve, reject) => resolve(value));
- static reject = (reason) => new MPromise((resolve, reject) => resolve(reason));
-
- // 关键是需要在循环中调用promise.then()方法向下执行,最后判断数组中所有promise执行完后,通过resolve返回结果
- static all = (promiseArr) => new MPromise((resolve, reject)=>{
- // 使用数组存放所有MPromise传入的参数数据
- let results = [];
- // 使用count记录处理的MPromise,每处理一个+1,直到最后一个处理完就返回参数数组
- let count = 0;
- promiseArr.forEach((promise,index)=>{
- promise.then(item=>{
- results[index] = item;
- count++;
- console.log(promise.value);
- // 注意此处用数组下标判断会出现问题:setTimeout()异步的会等results其他输出后第二次输出
- if(count === promiseArr.length){
- resolve(results);
- }
- });
-
- });
- })
- }
-
- // // MPromise类调用
- // let p = new MPromise((resolve, reject) => {
- // setTimeout(function () {
- // resolve("success");
- // // reject("error");
- // }, 1000)
- // });
- // p.then((data) => {
- // console.log(data);
- // return data
- // },err=>{
- // console.log(err);
- // }).then((data)=>{
- // console.log("第二次调用then",data);
-
- // })
-
- // MPromise.resolve("这是静态方法MPromise.resolve调用").then((data)=>{
- // console.log(data);
- // return data;
- // }).then(data=>{
- // console.log("第二次调用静态方法MPromise.resolve调用",data);
-
- // })
- // MPromise.reject("这是静态方法MPromise.reject调用").then((error)=>{
- // console.log(error);
- // })
-
- let p1 = new MPromise(1);
- let p2 = new MPromise((resolve, reject) => {
- setTimeout(function(){
- resolve("p2");
- }, 2000);
- })
- let p3 = new MPromise((resolve, reject) => {
- resolve("p3");
- })
- let p4 = new MPromise((resolve, reject) => {
- resolve("p4");
- })
-
- MPromise.all([p1, p2, p3, p4]).then(result => {
- console.log(result);
- });
-
-
- // // Promise类调用
- // let p = new Promise((resolve, reject) => {
- // // 执行resolve或者reject函数,并传入参数
- // setTimeout(function (){
- // resolve("success");
- // },1000)
- // });
- // p.then((data) => {
- // console.log(data);
- // })