Promise基础篇

2022-10-28 13:25:41

什么是Promise

MDN定义:Promise对象用于异步操作,他表示一个尚未完成且预计在未来完成的异步操作。
Promise是异步编程的解决方案,相较传统的解决方案更加合理和强大。

回调函数

request('value1','',function(data1){
    console.log('第一次请求成功', data1);request('value2', data1,function(data2){
        console.log('第二次请求成功', data2);request('value3', data2,function(data3){
            console.log('第三次请求成功', data3);//request... 继续请求},function(error3){
            console.log('第三次请求失败', error3);});},function(error2){
        console.log('第二次请求失败', error2);});},function(error1){
    console.log('第一次请求失败', error1);});

上述例子出现了多层嵌套,这就是常说的回调地狱,而使用Promise,可以利用then进行链式回调,将异步操作以同步操作的流程表示出来。

sendRequest('value1','').then(function(data1){
    console.log('第一次请求成功', data1);returnsendRequest('value2', data1);}).then(function(data2){
    console.log('第二次请求成功', data2);returnsendRequest('value3', data2);}).then(function(data3){
    console.log('第三次请求成功', data3);}).catch(function(error){//catch捕捉前面的错误
    console.log('sorry, 请求失败了', error);});

Promise有三种状态

  • pending:初始值
  • fulfilled:操作成功
  • rejected:操作失败

Promise的缺点:

  • Promise一旦新建就会执行,无法中途取消
  • 若不设置回调函数,Promise内部抛出错误,不会反映到外部
  • 处于pending状态时,无法得知目前是刚开始还是即将完成

Promise的基本用法

const promise=newPromise((resolve,reject)=>{if(/*异步操作成功*/){resolve(res);}else{/*异步操作失败*/reject(error);}})

我们构建一个PromisePromise接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由JavaScript引擎提供。
resolve 异步操作成功时调用,并将操作结果以参数传递出去。
reject 异步操作失败时调用,并将操作的报错以参数传递出去。

Promise实例生成后,使用then方法指定resolved状态和reject状态的回调函数

promise.then((value)=>{//success},(error)=>{//failure});

then方法可以接受两个回调函数作为参数,第一个函数是promise对象的状态改变为resolved是调用,第二个函数是promise对象状态改变为rejected时调用。第二个函数为可选。

Promise新建后会立即执行。then方法中指定的回调函数,将在当前脚本所有同步任务执行完成后才会执行

const promise=newPromise((resolve,reject)=>{
	console.log('success);resolve();})
promise.then(()=>{
	console.log('resolved');})
console.log('promsie')// success// promise// resolved

promise对象实现ajax操作:

constrequest=(param)=>{returnnewPromise((resolve,reject)=>{var xhr=newXMLHttpRequest();
		xhr.open("get", param.url,true);
		xhr.send(param.data);
		xhr.responseType="json";
		xhr.onreadystatechange=()=>{if(xhr.readyState===4){if(xhr.status===200){try{resolve(xhr.responseText+'success');}catch(err){reject(err)}}else{//failurereject(newError(xhr.statusText));}}}})}request(param).then((res)=>{
	console.log(res);},(error)=>{
	console.error(error);})

上述例子,request是对XMLHttpRequest对象的封装,用于发出一个http请求,并返回一个Promise对象。

Promise.prototype.then()

then 方法为Prommise实例添加状态改变时的回调函数,即resolved和rejected。
then方法返回一个新的Promise对象,因此可以采用链式写法。

Promise.prototype.catch()

catch方法用于指定发生错误时的回调函数。

request(param).then((res)=>{
	console.log(res);}).catch((error)=>{
	console.error(error);})//=========== 等同于 ===============request(param).then((res)=>{
	console.log(res);}).then(undefined||null,(error)=>{
	console.error(error);})

Promise抛出一个错误,就被catch的回调函数捕获

const promise=newPromise((resolve,reject)=>{thrownewError('error')});
promise.catch((error)=>{
	console.log(error);})

上面代码的写法等同于

const promise=newPromise((resolve,reject)=>{try{thrownewError('error')}catch{reject(error);}});

从以上代码可以看出,reject方法等同于抛出错误。
Promise对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。

const promise=newPromise((resolve,reject)=>{resolve(a+2)//此处报错 a未定义});
promise.then(()=>{
	console.log('promise');})setTimeout(()=>{
	console.log('promise test')},5000)// a is not defind// promise test

上面代码中,promise对象的内部语法有错,浏览器会打印错误提示,但不会终止脚本执行,5秒后会输出promise test,即promsie内部的错误不会影响到外部的代码。

Promise.resolve()

Promise.resolve能将现有的对象转为Promise对象,它可以看做是new Promise()的快捷方式。

Promise.resolve(value)//=============等同于===================newPromise(resolve=>{resolve(value);})

Promise.reject()

该方法和Promise.resolve()类似,也会返回一个Promise对象,该对象会进入rejected状态,

Promise.all()

Promise.all()用于将多个Promise实例,包装成一个新的Promise实例,该方法接受一个数组作为参数,数组的每一项都为一个Promise,若不是,会调用Promise.resolve()方法,将参数转换为Promise实例。它的状态由参数中的Promise实例决定。

  • 当数组中的Promise实例都为fulfilled,它的状态才会变为fulfilled,并将Promise的返回结果按参数的顺序,存入数组。
var p1=newPromise(resolve=>{setTimeout(resolve,2000,"frist")})var p2=newPromise(resolve=>{resolve('second')})var p3=newPromise(resolve=>{setTimeout(resolve,500,"third")})
Promise.all([p1,p2,p3]).then(value=>{
	console.log(value);})////["first","second","third"]
  • 当数组中的Promise实例其中之一的状态变为rejected,它的状态也会变为rejected,并把第一个被reject的Promise的返回值传给回调函数。
var p1=newPromise(resolve=>{setTimeout(resolve,1000,"first")})var p2=newPromise((resolve,reject)=>{setTimeout(reject,500,"second")})var p3=newPromise((resolve,reject)=>{setTimeout(reject,500,"third")})
Promise.all([p1,p2,p3]).then(value=>{
	console.log('resolve',value);},error=>{
	console.log('reject',error);})//// reject second

Promise.race()

该方法同样用于将多个Promie实例包装成一个新的Promise实例,它与Promise.all()方法一样,会将不是Promise实例的参数转换为Promise实例。与Promise.all()不同于,当数组中有一个实例改变了状态,它的状态就会改变,并把率先改变的Promise实例的返回值,传递给回调函数。

var p1=newPromise((resolve,reject)=>{setTimeout(reject,2000,'one');})var p2=newPromise((resolve,reject)=>{setTimeout(resolve,1000,'two');})

Promise.race([p1,p2]).then(value=>{
    console.log('resolve',value)},error=>{
    console.log('reject',error)})//// resolve two
  • 作者:MrAnother
  • 原文链接:https://blog.csdn.net/weixin_43153361/article/details/94442941
    更新时间:2022-10-28 13:25:41