1、promise
Promise 是异步编程的一种解决方案,所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。简言之,Promise就算用来封装异步函数的,有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
下面代码创造了一个 Promise 实例:
const promise=new Promise(function(resolve,reject){
if(1>0){
resolve('success');
}else{
reject('error');
}
})
Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是resolve 和reject 。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。Promise对象代表一个异步操作有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
resolve 函数的作用是:将 Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 fulfilled),在异步操作成功时调用,并将异步操作的结果作为参数传递出去;reject函数的作用是,将 Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise 实例生成以后,可以用 then方法、catch方法以及finally方法指定resolved状态和 rejected状态的回调函数。
promise.then((res)=>{
console.table(res);
}).catch((error)=>{
console.error(error);
}).finally(()=>{
console.log('最终执行');
})
Promise.then():当状态由pending变为fulfilled的时候执行该回调函数,
参数:回调函数,回调函数的参数为resolve函数传递过来的值
返回值:返回一个新的Promise实例对象,因此可以使用链式调用
Promise.catch():当状态由pending变为rejected的时候执行该回调函数
参数:回调函数,回调函数的参数为reject函数传递过来的值
返回值:返回一个新的Promise实例对象,因此可以使用链式调用
Promise.finally():当状态由pending变为fulfilled或者rejected的时候都执行该回调函数,
参数:回调函数,不需要传值
返回值:返回一个新的Promise实例对象
let p1 = Promise.resolve(1);
let p2 = Promise.resolve(2);
let p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
console.log(results); // 输出[1, 2, 3]
});
Promise.all([p1,p2]):用于将多个 Promise 实例,包装成一个新的 Promise 实例,
参数:数组,数组中的元素为Promise实例
返回值:Promise实例,当p1,p2状态都为fulfilled时候,该实例的状态才为fulfilled,此时p1,p2的返回值组成一个数组,传递给该实例的回调函数;只要p1,p2的返回值有一个变为rejected,该实例状态为rejected。
let p1 = Promise.reject('a')
let p2 = Promise.resolve('b')
let p3 = Promise.reject('c')
let p4 = Promise.resolve('d')
Promise.race([p1, p2, p3, p4]).then(res => {
console.log('成功', res); //返回数组
}).catch(err => {
console.log('失败', err);
})
//输出结果为c
let p1 = Promise.reject('a')
let p2 = Promise.resolve('b')
Promise.race([p1, p2]).then(res => {
console.log('成功', res); //返回数组
}).catch(err => {
console.log('失败', err);
})
输出结果为:失败 a
Promise.race([p1,p2]):用于将多个 Promise 实例,包装成一个新的 Promise 实例,
参数:数组,数组中的元素为Promise实例
返回值:Promise实例,当p1,p2之中有一个实例率先改变状态,该实例的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给该实例的回调函数。一个待定的Promise只要给定迭代中的一个promise解决或拒绝,就采用第一个promise的值作为它的值,从而异步地解析或拒绝。
2、generator
在Javascript中,一个函数一旦开始执行,就会运行到最后或遇到return时结束,运行期间不会有其它代码能够打断它,也不能从外部再传入值到函数体内,而Generator函数(生成器)的出现使得打破函数的完整运行成为了可能。
Generator函数有两个特征:
1.function关键字与函数名之间有个星号;
2.函数内部使用yield表达式 ;
3.直接调用 Generator函数并不会执行,也不会返回运行结果,而是返回一个遍历器对象;
4. 调用遍历器对象的next方法,可以得到 Generator函数内部的每一个状态。
function* myGenFun(){
yield 'one';
yield 'two';
yield 'three';
}
// 函数执行结果返回迭代器对象
let gen=myGenFun();
console.log(gen);//输出Object [Generator] {}
console.log(gen.next());//输出{ value: 'one', done: false }
console.log(gen.next());//输出{ value: 'two', done: false }
console.log(gen.next());//输出{ value: 'three', done: false }
console.log(gen.next());//输出{ value: undefined, done: true }
3、async
Async函数是generator函数的语法糖,在generator函数的基础上添加了一些更加方便用户操作的新特性。Async函数的执行和普通函数一致,只需要一行代码即可,因为他具有内置的执行。async与await对比*与yield有更好的语义。
async function test() {
return "async";
}
const result = test();
console.log(result);
如上所示,async 函数会返回一个Promise 对象。
async function fun() {
const b = await new Promise((resolve, reject)=>{
setTimeout(function(){
resolve('success')
});
})
console.log(b);
}
fun();//输出结果为:success
当 async 函数返回一个值时,Promise 的 resolve 方法会负责传递这个值;当 async 函数抛出异常时,Promise 的 reject 方法也会传递这个异常值。
async function test() {
const data = await "await";
console.log(data);
}
test();//输出结果为:await
await 用于等待一个异步任务执行完成的的结果,并且 await 只能出现在 async 函数中。await 操作符用于等待一个Promise 对象,并且返回 Promise 对象的处理结果(成功把resolve 函数参数作为await 表达式的值),如果等待的不是 Promise 对象,则用 Promise.resolve(xx) 转化。