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("执行完了");
相关推荐
腾讯TNTWeb前端团队1 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰5 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪5 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪5 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy6 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom6 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom6 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom7 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试