【JS异步编程】Promise快速实践

什么是异步编程

异步编程是一种编程方式,它可以让程序在执行一个可能长时间运行的任务的同时,继续对其他事件做出反应,而不必等待任务完成,直到任务执行完毕之后再来通知你(在js中是通过回调函数的形式)。异步编程可以提高程序的性能和响应能力,避免阻塞和等待。

一般来说,异步编程适用于以下场景(一些I/O密集型操作):

在这里插入图片描述

详细来说:

  • 不涉及共享资源,或对共享资源只读,即非互斥操作
  • 没有时序上的严格关系,或可以通过回调函数、Promise、async/await等方式处理时序逻辑
  • 不需要原子操作,或可以通过其他方式控制原子性
  • 常用于IO操作(如网络请求、文件读写、数据库操作等)等耗时操作,因为这些操作会比较影响用户体验和程序性能
  • 不影响主线程或主程序逻辑的执行

例如,在浏览器中,我们可以使用XMLHttpRequest或fetch API来发起异步的HTTP请求,这样就不会阻塞用户界面的交互。我们可以通过事件监听器或then方法来获取请求的结果,并进行相应的处理。

在Node.js中,我们可以使用fs模块来进行异步的文件操作,这样就不会阻塞主线程的事件循环。我们可以通过回调函数或Promise来获取操作的结果,并进行相应的处理。

JS异步编程概要理解

在js中有两种实现异步的方式:

  • 传统的回调函数
    在这里插入图片描述
  • Promise(理解为承诺,承诺在未来的某一个时间返回数据)

因为传统的回调函数的方式容易引起回调地狱,所以我们这里来看看Promise。

在这里插入图片描述
我们通过fetch请求一个地址之后,会立马获得一个Promise,我们随后可以调用它的then方法,并传递一个回调函数,如果这个请求在未来被成功完成,那么回调函数会被调起,请求的结果也会以参数的形式传递进来。
在这里插入图片描述
但如果光是这样Promise和回调函数就没有什么区别了。Promise的特点是可以用一种链式结构将多个异步操作串联起来:
在这里插入图片描述
比如这里的response.json()方法也会返回一个Promise,代表在未来的某个时刻将返回数据转换成为json格式,如果我们想要等它完成之后再执行其他操作,我们就可以在后面追加一个then,然后执行接下来的代码,比如说这里就是将转化后的json打印出来。

同时Promise中还涉及catch异常捕捉以及finally块,也方便了我们的开发工作。

再来说说async、await。它是基于promise之上的语法糖,可以让异步操作更加的简洁明了。

async将函数标名为异步函数,异步函数就是指返回值为Promise对象的函数,比如前面提到的fetch:
在这里插入图片描述

在异步函数中我们还可以调用其他的异步函数,不过这个时候我们不需要使用then,而是使用更加简洁的await语法。await会等待Promise完成之后
返回正确的结果。
在这里插入图片描述

await虽然看上去会暂停函数的执行,但是在等待的过程中js同样可以处理其他的任务,比如更新界面、运行其他的程序代码等等。这是因为await底层是基于Promise和事件循环机制实现的。

Promise是什么

抽象表达:

  1. Promise 是一门新的技术(ES6 规范)
  2. Promise 是 JS 中进行异步编程的新解决方案。(旧方案是单纯使用回调函数)

具体表达:

  1. 从语法上来说: Promise 是一个构造函数
  2. 从功能上来说: Promise 对象用来封装一个异步操作并可以获取其成功/失败的结果值

为什么要用Promise

①指定回调函数的方式更加灵活

  1. 旧的: 必须在启动异步任务前指定
  2. promise: 启动异步任务 => 返回promie对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定/多个)

②支持链式调用, 可以解决回调地狱问题
在这里插入图片描述

  1. 什么是回调地狱?

    • 回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调执行的条件
  2. 回调地狱的缺点?

    • 不便于阅读
    • 不便于异常处理
  3. 解决方案?

    • promise 链式调用
  4. 终极解决方案?

    • async/await

Promise的初体验

案例一

场景:点击按钮, 1s 后显示是否中奖(30%概率中奖)
若中奖弹出 恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券
若未中奖弹出 再接再厉

如果用原来的方式:

        //生成随机数
        function rand(m,n){
            return Math.ceil(Math.random() * (n-m+1)) + m-1;
        }
        //获取元素对象
        const btn = document.querySelector('#btn');
        //绑定单击事件
        btn.addEventListener('click', function(){
            定时器
            setTimeout(() => {
                //30%  1-100  1 2 30
                //获取从1 - 100的一个随机数
                let n = rand(1, 100);
                //判断
                if(n <= 30){
                    alert('恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券');
                }else{
                    alert('再接再厉');
                }
            }, 1000);

如果用Promise方法来做:

           //Promise 形式实现
            // resolve 解决  函数类型的数据
            // reject  拒绝  函数类型的数据
            const p = new Promise((resolve, reject) => {
                setTimeout(() => {
                    //30%  1-100  1 2 30
                    //获取从1 - 100的一个随机数
                    let n = rand(1, 100);
                    //判断
                    if(n <= 30){
                        resolve(n); // 将 promise 对象的状态设置为 『成功』
                    }else{
                        reject(n); // 将 promise 对象的状态设置为 『失败』
                    }
                }, 1000);
            });

            console.log(p);
            //调用 then 方法
            // value 值
            // reason 理由
            p.then((value) => {
                alert('恭喜恭喜, 奖品为 10万 RMB 劳斯莱斯优惠券, 您的中奖数字为 ' + value);
            }, (reason) => {
                alert('再接再厉, 您的号码为 ' + reason);
            });

        });

代码解释
①promise 对象用来封装一个异步操作,所以我们把etTimeout()方法放在了其中。

②Promise实例化要接收一个函数类型的值,而且这个函数有两个形参(最好是命名为resolve,和reject),并且resolve,和reject这两个形参也是函数类型,并且

  • 在异步任务成功的时候调用resolve()
  • 在异步任务失败的时候调用reject()

而这两个函数的作用就是:

  • resolve()将Promise对象的状态变为成功
  • reject()将Promise对象的状态变为失败

这种状态的改变,是为了去影响后面then中相应方法的回调。

③Promise对象的then方法接受两个参数,且两个参数都是函数类型的值。其中:

  • 第一个函数是对象成功时的回调
  • 第二个函数是对象失败时的回调

④前面我们提到过promise 对象用来封装一个异步操作并可以获取其成功/失败的结果值

我们可以将要返回的值,传给resolve()和 reject()中,然后将then方法中的两个方法传入形参(一般第一个函数的形参为value,第二个函数的形参为reason),通过这两个形参就可以拿到结果值了。

案例二:Promise对Ajax操作的封装

<body>
    <div class="container">
        <h2 class="page-header">Promise 封装 AJAX 操作</h2>
        <button class="btn btn-primary" id="btn">点击发送 AJAX</button>
    </div>
    <script>
        //接口地址 https://api.apiopen.top/getJoke
        //获取元素对象
        const btn = document.querySelector('#btn');

        btn.addEventListener('click', function(){
            //创建 Promise
            const p = new Promise((resolve, reject) => {
                //1.创建对象
                const xhr = new XMLHttpRequest();
                //2. 初始化
                xhr.open('GET', 'https://api.apiopen.top/getJoke');
                //3. 发送
                xhr.send();
                //4. 处理响应结果
                xhr.onreadystatechange = function(){
                    if(xhr.readyState === 4){
                        //判断响应状态码 2xx   
                        if(xhr.status >= 200 && xhr.status < 300){
                            //控制台输出响应体
                            resolve(xhr.response);
                        }else{
                            //控制台输出响应状态码
                            reject(xhr.status);
                        }
                    }
                }
            });
            //调用then方法
            p.then(value=>{
                console.log(value);
            }, reason=>{
                console.warn(reason);
            });
        });
    </script>
</body>

Promise的基本流程

在这里插入图片描述

封装Ajax的请求

<body>
    <script>
        /**
         * 封装一个函数 sendAJAX 发送 GET AJAX 请求
         * 参数   URL
         * 返回结果 Promise 对象
         */
        function sendAJAX(url){
            return new Promise((resolve, reject) => {
                const xhr = new XMLHttpRequest();
                xhr.responseType = 'json';
                xhr.open("GET", url);
                xhr.send();
                //处理结果
                xhr.onreadystatechange = function(){
                    if(xhr.readyState === 4){
                        //判断成功
                        if(xhr.status >= 200 && xhr.status < 300){
                            //成功的结果
                            resolve(xhr.response);
                        }else{
                            reject(xhr.status);
                        }
                    }
                }
            });
        }
    
        sendAJAX('https://api.apiopen.top/getJok')
        .then(value => {
            console.log(value);
        }, reason => {
            console.warn(reason);
        });
    </script>
</body>

Promise 的状态改变

Promise的状态是Promise对象的属性,叫做PromiseState。
他一共有三个值:

  • pending 未决定的
  • resolved / fullfilled 成功
  • rejected 失败

而Promise的状态改变情况只有两种

  1. pending 变为 resolved
  2. pending 变为 rejected

且一个 promise 对象只能改变一次
无论变为成功还是失败, 都会有一个结果数据
成功的结果数据一般称为 value, 失败的结果数据一般称为 reason

Promise对象结果属性

Promise实例对象中还有一个属性PromiseResult,这个属性中保存着异步任务成功或失败的结果

这个结果只有两个东西可以进行修改:

  • resolve()
  • reject()

在这两个函数作出修改之后,在后续的then回调方法中,就又可以把结果给取出来。

Promise的工作流程

在这里插入图片描述

Promise的API

Promise 构造函数: Promise (excutor) {}
(1) executor 函数: 执行器 (resolve, reject) => {}
(2) resolve 函数: 内部定义成功时我们调用的函数 value => {}
(3) reject 函数: 内部定义失败时我们调用的函数 reason => {}

说明: executor 会在 Promise 内部立即同步调用,异步操作在执行器中执行

Promise.prototype.then 方法: (onResolved, onRejected) => {}
(1) onResolved 函数: 成功的回调函数 (value) => {}
(2) onRejected 函数: 失败的回调函数 (reason) => {}

说明: 指定用于得到成功 value 的成功回调和用于得到失败 reason 的失败回调返回一个新的 promise 对象

Promise.prototype.catch 方法: (onRejected) => {}
(1) onRejected 函数: 失败的回调函数 (reason) => {}

说明: then()的语法糖,只能指定失败的回调, 相当于: then(undefined, onRejected)

例如:

<script>
        //
        let p = new Promise((resolve, reject) => {
            // ** 同步调用
            // console.log(111);
            //修改 promise 对象的状态
            reject('error');
        });

        // console.log(222);

        //执行 catch 方法
        p.catch(reason => {
            console.log(reason);
        });
    </script>

Promise.resolve 方法

Promise.resolve 方法: (value) => {}
(1) value: 成功的数据promise 对象
说明: ①返回一个成功/失败的 promise 对象
②resolve方法是属于Promise的方法,而不是Promise对象的方法。

例如:

<script>
        //
        let p1 = Promise.resolve(521);
        //如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象,并且其结果为传入的参数
        //如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果
        let p2 = Promise.resolve(new Promise((resolve, reject) => {
            // resolve('OK');
            reject('Error');
        }));
        // console.log(p2);
        p2.catch(reason => {
            console.log(reason);
        })
    </script>

如果返回的是错误的Promise对象,那么浏览器会有一个报错,此时可以用catch进行处理。

Promise.reject 方法

Promise.reject 方法: (reason) => {}
(1) reason: 失败的原因
说明: 返回一个失败的 promise 对象,失败的结果为传入的值。

例如:

<script>
        // let p = Promise.reject(521);
        // let p2 = Promise.reject('iloveyou');
        let p3 = Promise.reject(new Promise((resolve, reject) => {
            resolve('OK');
        }));
        //即使传入了一个成功的对象他也只会返回一个错误的对象
        console.log(p3);
    </script>

Promise.all 方法

Promise.all 方法: (promises) => {}
(1) promises: 包含 n 个 promise 的数组
说明: 返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败。如果成功,则其结果为所有成功Promise对象结果组成的数组,如果失败,则其结果为失败的Promise的结果(不是多个失败的结果,因为第一个失败的时候就直接return了,所以只会返回第一个)。

<script>
        let p1 = new Promise((resolve, reject) => {
            resolve('OK');
        })
        // let p2 = Promise.resolve('Success');
        let p2 = Promise.reject('Error');
        let p3 = Promise.resolve('Oh Yeah');
        
        //
        const result = Promise.all([p1, p2, p3]);

        console.log(result);
    </script>

Promise.race 方法

Promise.race 方法: (promises) => {}
(1) promises: 包含 n 个 promise 的数组
说明: 返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的结果状态

<script>
        let p1 = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('OK');
            }, 1000);
        })
        let p2 = Promise.resolve('Success');
        let p3 = Promise.resolve('Oh Yeah');

        //调用
        const result = Promise.race([p1, p2, p3]);

        console.log(result);
    </script>

如何改变 promise 的状态?

要想修改Promise对象的状态,我们有三种办法:

  • 用resolve()函数,使状态由pending --> fullfilled
  • 用reject()函数,使状态由pending --> rejected
  • 抛出错误,使状态由pending --> rejected

例如:

     <script>
        let p = new Promise((resolve, reject) => {
            //1. resolve 函数
            // resolve('ok'); // pending   => fulfilled (resolved)
            //2. reject 函数
            // reject("error");// pending  =>  rejected 
            //3. 抛出错误
            // throw '出问题了';
        });

        console.log(p);
    </script>

一个 promise 指定多个成功/失败回调函数, 都会调用吗?

当 promise 改变为对应状态时都会调用

例如:

   <script>
        let p = new Promise((resolve, reject) => {
            // resolve('OK');
        });

        ///指定回调 - 1
        p.then(value => {
            console.log(value);
        });

        //指定回调 - 2
        p.then(value => {
            alert(value);
        });
    </script>

改变 promise 状态和指定回调函数谁先谁后?

  • (1) 都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
  • (2) 如何先改状态再指定回调?
    ① 在执行器中直接调用 resolve()/reject()
    ② 延迟更长时间才调用 then()
  • (3) 什么时候才能得到数据?
    ① 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据
    ② 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据

promise.then()返回的新 promise 的结果状态由什么决定?

(1) 简单表达: 由 then()指定的回调函数执行的结果决定

(2) 详细表达:
① 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常
② 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值
③ 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果

例如:

    <script>
        let p = new Promise((resolve, reject) => {
            resolve('ok');
        });
        //执行 then 方法
        let result = p.then(value => {
            // console.log(value);
            //1. 抛出错误
            // throw '出了问题';
            //2. 返回结果是非 Promise 类型的对象
            // return 521;
            //3. 返回结果是 Promise 对象
            // return new Promise((resolve, reject) => {
            //     // resolve('success');
            //     reject('error');
            // });
        }, reason => {
            console.warn(reason);
        });

        console.log(result);
    </script>

如果没有return则默认返回undefined

promise 如何串连多个操作任务?

(1) promise 的 then()返回一个新的 promise, 可以利用此特点构成 then()的链式调用
(2) 通过 then 的链式调用串连多个同步/异步任务

例如:

<script>
        let p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('OK');
            }, 1000);
        });

        p.then(value => {
            return new Promise((resolve, reject) => {
                resolve("success");
            });
        }).then(value => {
            console.log(value);
        }).then(value => {
            console.log(value); //此value为undefined
        })
    </script>

promise 异常传透

(1) 当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调,
(2) 前面任何操作出了异常, 都会传到最后失败的回调中处理

异常处理的常规逻辑,如果在每一层都对应的去处理相应的异常这很麻烦,我们可以简单的把这些异常汇聚到一个范围一起处理。就跟java异常处理中,我们可以把异常往“上”抛,在一个调用者中进行集中的处理。

例如:

    <script>
        let p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('OK');
                // reject('Err');
            }, 1000);
        });

        p.then(value => {
            // console.log(111);
            throw '失败啦!';
        }).then(value => {
            console.log(222);
        }).then(value => {
            console.log(333);
        }).catch(reason => {
            console.warn(reason);
        });
    </script>

如何终断Promise链

(1) 当使用 promise 的 then 链式调用时, 在中间中断, 不再调用后面的回调函数
(2) 办法: 在回调函数中返回一个 pendding 状态的 promise 对象(因为then方法只能对状态为fullfilled/rejected的Promise对象进行相应的回调)

例如:

    <script>
        let p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('OK');
            }, 1000);
        });

        p.then(value => {
            console.log(111);
            //有且只有一个方式
            return new Promise(() => {});
        }).then(value => {
            console.log(222);
        }).then(value => {
            console.log(333);
        }).catch(reason => {
            console.warn(reason);
        });
    </script>

自定义Promise

定义整体结构

/*
自定义 Promise
*/
(function (window) {
/*
Promise 构造函数
excutor: 内部同步执行的函数 (resolve, reject) => {}
*/
  	function Promise(excutor) {
	}

/*
为 promise 指定成功/失败的回调函数
函数的返回值是一个新的 promise 对象
*/
	Promise.prototype.then = function (onResolved, onRejected) {
	}
/*
为 promise 指定失败的回调函数
是 then(null, onRejected)的语法糖
*/
	Promise.prototype.catch = function (onRejected) {
	}
/*
返回一个指定了成功 value 的 promise 对象
*/
	Promise.resolve = function (value) {
	}
/*
返回一个指定了失败 reason 的 promise 对象
*/
	Promise.reject = function (reason) {
	}
/*
返回一个 promise, 只有 promises 中所有 promise 都成功时, 才最终成功, 只要有一个失败就直接
失败
*/
	Promise.all = function (promises) {
	}
/*
返回一个 promise, 一旦某个 promise 解决或拒绝, 返回的 promise 就会解决或拒绝。
*/
	Promise.race = function (promises) {
	}

// 暴露构造函数
	window.Promise = Promise
})(window)

Promise 构造函数的实现

/*
Promise 构造函数
excutor: 内部同步执行的函数 (resolve, reject) => {}
*/
function Promise(excutor) {
	const self = this
	self.status = 'pending' // 状态值, 初始状态为 pending, 成功了变为
	resolved, 失败了变为 rejected
	self.data = undefined // 用来保存成功 value 或失败 reason 的属性
	self.callbacks = [] // 用来保存所有待调用的包含 onResolved 和 onRejected 回调函数的对象的数组
/*
异步处理成功后应该调用的函数
value: 将交给 onResolve()的成功数据
*/
	function resolve(value) {
		if(self.status!=='pending') { // 如果当前不是 pending, 直接结束
			return
		}
// 立即更新状态, 保存数据
		self.status = 'resolved'
		self.data = value
// 异步调用所有待处理的 onResolved 成功回调函数
		if (self.callbacks.length>0) {
			setTimeout(() => {
				self.callbacks.forEach(obj => {
					obj.onResolved(value)
				})
			})
		}
	}
/*
异步处理失败后应该调用的函数
reason: 将交给 onRejected()的失败数据
*/
	function reject(reason) {
		if(self.status!=='pending') { // 如果当前不是 pending, 直接结束
			return
		}
// 立即更新状态, 保存数据
		self.status = 'rejected'
		self.data = reason
// 异步调用所有待处理的 onRejected 回调函数
		setTimeout(() => {
			self.callbacks.forEach(obj => {
				obj.onRejected(reason)
			})
		})
	}

	try {
// 立即同步调用 excutor()处理
		excutor(resolve, reject
	} catch (error) { // 如果出了异常, 直接失败
		reject(error)
	}
}

promise.then()/catch()的实现

Promise.prototype.then = function (onResolved, onRejected) {
	const self = this
// 如果 onResolved/onRejected 不是函数, 可它指定一个默认的函数
	onResolved = typeof onResolved === 'function' ? onResolved : value => value // 指定返回的 promise 为一个成功状态, 结果值为 value
	onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason} // 指定返回的 promise 为一个失败状态, 结果值为 reason
// 返回一个新的 promise 对象
	return new Promise((resolve, reject) => {
/*
专门抽取的用来处理 promise 成功/失败结果的函数
callback: 成功/失败的回调函数
*/
		function handle(callback) {
// 1. 抛出异常 ===> 返回的 promise 变为 rejected
			try {
				const x = callback(self.data)
// 2. 返回一个新的 promise ===> 得到新的 promise 的结果值作为返回的promise 的结果值
				if (x instanceof Promise) {
					x.then(resolve, reject) // 一旦 x 成功了, resolve(value), 一旦 x失败了: reject(reason)
				} else {
// 3. 返回一个一般值(undefined) ===> 将这个值作为返回的 promise 的成功值
					resolve(x)
				}
			} catch (error) {
				reject(error)
			}
		}
		if (self.status === 'resolved') { // 当前 promise 已经成功了
			setTimeout(() => {
				handle(onResolved)
			})
		} else if (self.status === 'rejected') { // 当前 promise 已经失败了
			setTimeout(() => {
				handle(onRejected)
			})
		} else { // 当前 promise 还未确定 pending
// 将 onResolved 和 onRejected 保存起来
			self.callbacks.push({
				onResolved(value) {
					handle(onResolved)
				},
				onRejected(reason) {
					handle(onRejected)
				}
			})
		}
	})
}

/*
为 promise 指定失败的回调函数
是 then(null, onRejected)的语法糖
*/
Promise.prototype.catch = function (onRejected) {
	return this.then(null, onRejected)
}

Promise.resolve()/reject()的实现

/*
返回一个指定了成功 value 的 promise 对象
value: 一般数据或 promise
*/
Promise.resolve = function (value) {
	return new Promise((resolve, reject) => {
		if (value instanceof Promise) {
			value.then(resolve, reject)
		} else {
			resolve(value)
		}
	})
}
/*
返回一个指定了失败 reason 的 promise 对象
reason: 一般数据/error
*/
Promise.reject = function (reason) {
	return new Promise((resolve, reject) => {
		reject(reason)
	})
}

Promise.all/race()的实现

/*
返回一个新的 promise 对象, 只有 promises 中所有 promise 都产生成功 value 时, 才
最终成功, 只要有一个失败就直接失败
*/
Promise.all = function (promises) {
// 返回一个新的 promise
	return new Promise((resolve, reject) => {
// 已成功的数量
		let resolvedCount = 0
// 待处理的 promises 数组的长度
		const promisesLength = promises.length
// 准备一个保存成功值的数组
		const values = new Array(promisesLength)
// 遍历每个待处理的 promise
		for (let i = 0; i < promisesLength; i++) {
// promises 中元素可能不是一个数组, 需要用 resolve 包装一下
			Promise.resolve(promises[i]).then(
				value => {
// 成功当前 promise 成功的值到对应的下标
					values[i] = value
// 成功的数量加 1
					resolvedCount++
// 一旦全部成功
					if(resolvedCount===promisesLength) {
// 将所有成功值的数组作为返回 promise 对象的成功结果值
						resolve(values)
					}
				},
				reason => 
				// 一旦有一个promise产生了失败结果值, 将其作为返回promise对象的失败结果值
					reject(reason)
				}
			)
		}
	})
}
/*
返回一个 promise,一旦某个 promise 解决或拒绝, 返回的 promise 就会解决或拒绝。
*/
Promise.race = function (promises) {
// 返回新的 promise 对象
	return new Promise((resolve, reject) => {
// 遍历所有 promise
		for (var i = 0; i < promises.length; i++) {
			Promise.resolve(promises[i]).then(
				(value) => { // 只要有一个成功了, 返回的 promise 就成功了
					resolve(value)
				},
				(reason) => { // 只要有一个失败了, 返回的结果就失败了
					reject(reason)
				}
			)
		}
	})
}

Promise.resolveDelay()/rejectDelay()的实现

/*
返回一个延迟指定时间才确定结果的 promise 对象
*/
Promise.resolveDelay = function (value, time) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			if (value instanceof Promise) { // 如果 value 是一个 promise, 取这个promise 的结果值作为返回的 promise 的结果值
				value.then(resolve, reject) // 如果 value 成功, 调用resolve(val), 如果 value 失败了, 调用 reject(reason)
			} else {
				resolve(value)
			}
		}, time);
	})
}

/*
返回一个延迟指定时间才失败的 Promise 对象。
*/
Promise.rejectDelay = function (reason, time) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			reject(reason)
		}, time)
	})
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十八岁讨厌编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值