Promise

Promise

Promise是异步编程的一种解决方案,

Promise 状态

  • pending:进行中
  • fulfilled:已成功
  • rejected:已失败

Promise 实例化对象的状态只能从pending ->fulfilled,pending ->rejected,不能从fulfilled到reject或者反之也不行

基本用法

js 复制代码
console.log("①");
new Promise((resolve, reject) => {
    console.log("②");
    if(true){
    	resolve();
    }else{
		reject()
	}
    
    console.log("③");
})
console.log("④");

Promise 构造函数接受一个函数作为参数,该函数有两个参数resolvereject

  • resolve:将Promise对象的状态从未完成 变成成功
  • reject:将Promise对象的状态从未完成变成失败
js 复制代码
const promise = new Promise((resolve,reject) => {
	if(true){
		resolve('success');
	}else{
		reject('fail')
	}
	
})
promise.then((res) =>{},(err)=>{})
  • resolve 后的Promise
  • reject后的Promise
  • Promise新建后就会立即执行
js 复制代码
new Promise((resolve,reject) => { 
	console.log("①")
	resolve();
	console.log("②")
})

执行结果是① 和 ② 顺序打印

then

  • then 中返回 非Promise
  • then 中返回Promise实例
  • 抛出异常
  • 没有return 内容,默认是fulfilled
js 复制代码
const p = new Promise((resolve, reject) => {
    resolve("success")
})
const p1 = p.then(res => {
    return res;
})
console.log(p1, "p1");
const p2 = p.then(res => {
    return new Promise(() => { });
})
console.log(p2, "p2");
const p3 = p.then(res => {
    throw new Error("error")
})
console.log(p3, "p3");
const p4 = p.then(() => {

})
console.log(p4, "p4");

链式调用

js 复制代码
new Promise((resolve, reject) => {
    console.log("1");
    resolve("2")
    console.log("3");
    reject("4")
}).then(res => {
    console.log("5>>>", res);
    return res
}).then(res => {
    console.log("6", ">>>", res);
}).then((res => {
    console.log("7", ">>>", res);
    return new Promise((resolve, reject) => {
        console.log("8");
        reject("9")
    })
})).then((res) => {
    console.log("10", ">>>", res);

}).catch(err => {
    console.log("11", "error>>>", err);
})
console.log("执行完了");

cath

用于指定发生错误时的回调函数

js 复制代码
new Promise((resolve, reject) => {
    console.log(1);
    reject("error>>>>>>>>")
}).catch(err => {
    console.log(2);
    return new Promise((resolve, reject) => {
        console.log("err", err);
        resolve(3)
    })
}).then(res => {
    console.log("res", res);
})
js 复制代码
const p = new Promise((resolve, reject) => {
    resolve(n + 1) // n is not defined
})
p.then(res => {
    console.log(res);
})
setTimeout(() => {
    console.log(1);
}, 2000)

上述代码中,存在语法错误,浏览器运行到这一行,会打印错误提示,但是不会退出进程、终止脚本执行

js 复制代码
const p = new Promise((resolve, reject) => {
    reject("error")
}).catch(err => {
    console.log(err);
    console.log(x);
}).catch(err => {
    console.log("catch =>>> error");

})

第二个catch方法用来捕获前一个catch方法抛出的错误

finally

finally()方法用于指定不管Promise对象状态如何,都会执行的操作

js 复制代码
const p = new Promise((resolve, reject) => {
    resolve(1);
    reject(2);
}).then(res => {
    console.log("success");

}).catch(err => {
    console.log("error");

}).finally(() => {
    console.log("finally");

}).finally(() => {
    console.log("finally2");
}).then((res) => {
    console.log(res, "res1");
}).then((res) => {
    console.log(res, "res2");
}).catch((err) => {
    console.log(err, "err");
})

Promise.all()

Promise.all()方法用于将多个Promise实例,包装成一个新的Promise实例

js 复制代码
const p1 = new Promise((resolve, reject) => {
    resolve("p1")
})
const p2 = new Promise((resolve, reject) => {
    resolve("p2")
})
const p3 = new Promise((resolve, reject) => {
    resolve("p3")
})
Promise.all([p1, p2, p3]).then(res => {
    console.log(res);
})
js 复制代码
const p1 = new Promise((resolve, reject) => {
    resolve("p1")
})
const p2 = new Promise((resolve, reject) => {
    resolve("p2")
})
const p3 = new Promise((resolve, reject) => {
    resolve("p3")
})
const p4 = new Promise((resolve, reject) => {
    reject("p4")
})
Promise.all([p1, p2, p3, p4]).then(res => {
    console.log(res);
}).catch(err => {
    console.log("err>>", err);
})

Promise.race()

js 复制代码
const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("p1")
    }, 5000)
})
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("p2")
    }, 3000)
})
const p3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("p3")
    }, 3000)
})
const p4 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("p4")
    }, 2000);
})
const p = Promise.race([p1, p2, p3, p4]).then(res => {
    console.log("res>>>", res);
    return res;
}).catch(err => {
    console.log("err>>", err);

})
console.log(p, "p");

以上代码中,只要p1、p2、p3、p4 之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的回调函数

Promise.allSettled()

用来确定一组异步操作是否都结束了(无论成功或者失败)

只有等到参数数组中所有的Promise对象都发生变更(不管是fulfilled还是rejected),返回的Promise对象才会发生状态变更

js 复制代码
const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("p1")
    }, 5000)
})
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("p2")
    }, 3000)
})
const p3 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject("p3")
    }, 3000)
})
console.time("p")
await Promise.allSettled([p1, p2, p3]).then(res => {
    console.log("res>>>", res);
    return res;
}).catch(err => {
    console.log("err>>", err);

})
console.timeEnd("p")
console.log("执行完了");

上面代码中,只有等Promise.allSettled()都执行完成后,才会执行打印,该方法返回新的Promise实例,一定状态变更,状态总是fulfilled,不会变成rejected,状态变成fulfilled后,它的回调函数会接收到一个数组作为参数,该数组的每个成员对应前面数组的每个Promise对象

Promise.any()

js 复制代码
const p1 = Promise.any([Promise.resolve(1), Promise.resolve(-1), Promise.reject(Infinity)]).then(res => {
    console.log(res, "res");//1
})
const p2 = Promise.any([Promise.reject(2), Promise.resolve(100), Promise.reject(Infinity)]).then(res => {
    console.log(res, "res"); //100
})
const p3 = Promise.any([Promise.reject(Infinity), Promise.reject(-1), Promise.reject(1000)]).then(res => {
    console.log(res, "res");
}).catch(err => {
    console.log(err, "err"); // AggregateError: All promises were rejected 'err'
    console.log(err instanceof AggregateError, "err"); //true 'err'
})

Promise.any()方法的参数数组包含Promise操作,其中只要有一个变成fulfilledPromise.any()返回的对象就变成了fulfilled,如果都变成rejected那么就会变成rejected

Promise.resolve()

有时候需要将对象转为Promise对象,Promise.resolve()方法就起到了作用。

  • 参数是Promise实例
    如果参数是Promise实例,那么将不做任何修改,返回这个实例;
  • 如果参数是一个thenable对象
js 复制代码
const thenAble = {
    then(resolve, reject) {
        resolve("thenAble>> thenFuction")
    }
}
Promise.resolve(thenAble).then(res => {
    console.log(res, "res"); // thenAble>> thenFuction
})

Promise.resolve()方法会将这个对象转为Promise 对象,然后立即执行其中的then方法

  • 参数不是具有then()方法的对象,或者是不是对象
    如果参数是一个原始值,或者不具有then()方法的对象,这Promise.resolve()方法返回一个新的Promise对象,状态为resolved
js 复制代码
const p = Promise.resolve("none")
console.log(p);
  • 不带任何参数
js 复制代码
setTimeout(() => {
    console.log(1);
}, 2000)
Promise.resolve().then((res) => {
    console.log(res);

    console.log(2);
})
console.log(3);
// 3
// undefined
// 1

Promise.reject()

js 复制代码
Promise.reject("1").then(res => {
    console.log(res, "res");

}).catch(err => {
    console.log(err, "err"); 
})
// 1 err

Promise.try()

有一个函数,不知道它是同步执行还是异步执行,想用一种方法如果它是同步的代码就让他同步执行,异步就异步执行;

  • 方法一
js 复制代码
function f1() {
    setTimeout(() => {
        console.log("异步代码");
    }, 2000)
}
function f2() {
    console.log("同步代码");
}
Promise.try(() => {
    f1()
    f2()
}).then(res => {
    console.log(res, "res");
}).catch(err => {
    console.log(err, "err");
})
console.log("执行完了");
相关推荐
JIngJaneIL2 分钟前
篮球论坛|基于SprinBoot+vue的篮球论坛系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·篮球论坛系统
沐知全栈开发1 小时前
Python3 集合
开发语言
Jonathan Star1 小时前
用Python轻松提取视频音频并去除静音片段
开发语言·python·音视频
程序猿阿伟2 小时前
《首屏加载优化手册:Vue3+Element Plus项目提速的技术细节》
前端·javascript·vue.js
Evand J2 小时前
【自适应粒子滤波MATLAB例程】Sage Husa自适应粒子滤波,用于克服初始Q和R不准确的问题,一维非线性滤波。附下载链接
开发语言·matlab·卡尔曼滤波·自适应滤波·非线性
尘觉2 小时前
面试-浅复制和深复制?怎样实现深复制详细解答
javascript·面试·职场和发展
hd51cc2 小时前
C++ 类的学习(四) 继承
开发语言·c++·学习
编码追梦人3 小时前
深耕 Rust:核心技术解析、生态实践与高性能开发指南
开发语言·后端·rust
2301_772093563 小时前
KVSTORE_Pain point_tuchuang_ROS2
java·开发语言·1024程序员节
刘火锅3 小时前
Java 17 环境下 EasyPoi 反射访问异常分析与解决方案(ExcelImportUtil.importExcelMore)
java·开发语言·python