一、概念
异步编程与Promise的关系:
Promise 是异步编程的一种解决方案:从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。promise有三种状态: pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。
二、原理
Promise 也还是使用回调函数,只不过是把回调封装在了内部,使用上一直通过 then 方法的链式调用,使得多层的回调嵌套看起来变成了同一层的,书写上以及理解上会更直观和简洁一些。
三、用法
Promise基本语法:
promise有三种状态:分别是pending,fulfilled,rejected三种,该三种状态体现的是当前promise实例的状态,一旦改变就不会再变,转变过程为pending向着fulfilled和rejected转变。
let p = new Promise()
从语法上讲,promise是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
let p = new Promise((resolve,reject)=>{
//
})
ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。
resolve函数的作用是:将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 fulfilled),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用是:将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
const promise = new Promise(function (resolve, reject) {
//...do something
if (/*异步操作成功*/) {
resolve(value);
} else {
reject(error);
}
});
在Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
then方法可以接受两个回调函数作为参数。
第一个回调函数是Promise对象的状态变为fulfilled时调用,
第二个回调函数是Promise对象的状态变为rejected时调用。
其中,第二个函数是可选的,不一定要提供。
这两个函数都接受Promise对象传出的值作为参数。
promise.then(function(value){
//value
}, function(error){
//error
});
Promise 新建后立即执行,然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行。
Promise对象的 then (onfulfilled, onrejected) 方法会返回一个新的Promise对象,then方法中onfulfilled回调函数会作为一个新的Promise对象构造时的执行器函数,且返回值作为新Promise对象fulfilled状态下的结果,即value值
该value值会传递给新Promise对象的then()方法中的onfulfilled回调函数,同理,如果then方法中onfulfilled函数发生错误,则会将新Promise对象的状态定型为rejected
then方法始终会返回一个新的Promise对象,可以代码显式创建,也可以由then方法内部隐式创建,如果需要在then方法中执行一个异步任务,就需要显式创建一个新的Promise对象。
Promise.resolve()方法,返回一个具有给定值的 Promise 对象。如果传入的参数是一个 Promise 实例,则该实例将被直接返回;否则,将创建一个新的 Promise 对象,并将传入的参数作为 Promise 对象的fulfilled值。
一般,不要在then方法中定义rejected状态的回调函数,而应该总是使用catch方法。
当需要将多个Promise任务一起执行时,可以使用Promise.all( )方法。
Promise.all( )实参是所有Promise实例的字面量组成的数组,执行完毕的结果是所有输出结果的所组成的数组
var p1 = new Promise((res,rej) => {
setTimeout(() => {
res('p1');
}, 3000);
})
var p2 = new Promise((res,rej) => {
setTimeout(() => {
res('p2');
}, 2000);
})
var p3 = new Promise((res,rej) => {
setTimeout(() => {
res('p3');
}, 1000);
})
Promise.all([p1,p2,p3]).then((r) => {
console.log(r);
}).catch((err) => {
console.log(err.message);
})
async/await的作用与用法
async/await 是 promise 的语法糖,作用是为了让 Promise 更加完善,让代码看上去更加同步。
async函数是 AsyncFunction 构造函数的实例, 并且其中允许使用await关键字。
async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。
async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。因此对async函数可以直接then,返回值就是then方法传入的函数。
await 也是一个修饰符,只能放在async定义的函数内。可以理解为 等待。
function log(time){
setTimeout(function(){
console.log(time);
},time)
}
async function fun(){
let a = await log(1000);
let b = await log(3000);
let c = await log(2000);
console.log(a);
console.log(1)
}
fun();
//输出顺序:undefined 1 1000 2000 3000