异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理且更强大异步是非阻塞的
Promise里的函数是同步调用的,异步操作在执行器中执行var promise = new Promise(传一个函数)var promise = new Promise(function (resolve, reject)) {if(异步操作成功){resolve(value)} else {reject(error)}}
Promise的状态
Promise的状态实例对象中的一个属性 PromiseState有三个状态:1、pending 初始状态2、pending = resolved/fullfilled 实现 操作成功3、pending = rejected 拒绝 操作失败tips:只会变为成功和失败两个状态,且一个promise对象只能改变一次,无论变为成功还是失败,都会有一个结果数据,成功的结果数据一般称为value,失败的结果数据一般称为reason
当promise状态发生改变,就会触发then()里的响应函数处理后续步骤
Promise对象的值
实例对象中的另一个属性 PromiseResult保存的是异步任务失败/成功的结果resolvereject
Promise.resolve
如果传入的参数为非Promise对象,则返回的结果为成功promise对象如果传入的参数为Promise对象,则参数的结果决定了resolve的结果let p1 = Promise.resolve(521)console.log(p1);let p2 = Promise.resolve(new Promise(resolve, reject) => {reject('Error')})p2.catch(err => {console.log(err)})
Promise.reject
无论传入什么参数,返回的结果都是失败let p1 = Promise.reject(521)console.log(p1);
promise.all
promise.all可以将多个promise实例包装成一个新的Promise实例,同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值tips:要全部成功才返回一个成功结果的数组碰到一个失败则直接返回第一个失败的结果
let p1 = new Promise(function(resolve, reject) {resolve('success1')})let p2 = new Promise(function(resolve, reject) {resolve('success2')})let p3 = Promise.reject('error')Promise.all([p1, p2]).then(function(res){console.log(res);}).catch(err=>{console.log(err);})Promise.all([p3, p1]).then(function(res){console.log(res);}).catch(err=>{console.log(err);})Promise.all([p1, p3, p2]).then(res=>{console.log(res);}).catch(err=>{console.log(err);})
Promise.race
顾名思义,Promise.race就是赛跑的意思,意思就是说,Promise.race([p1,p2,p3])里面哪个结果获得的快,就返回哪个结果,不管结果本身是成功状态还是失败状态
var promise1 = new Promise((resolve, reject)=> {setTimeout(function(){if(true){resolve('success')}else{reject('lose')}},1000)})var promise2 = new Promise((resolve, reject)=>{if(false){resolve('success2')}else{reject('lose2')}})Promise.race([promise1, promise2]).then(res=>{console.log(res);}).catch(err=>{console.log(err);})
改变对象的三种方式
1、resolve函数如果当前是pending就会变为resolved2、reject函数如果当前是pending就会变为rejected3、抛出错误如果当前是pending就会变为rejectedthrow 'error'
一个promise指定多个成功/失败回调函数,都会调用吗?
只要状态发生改变则都会调用,状态没有改变则都不调用let p1 = new Promise((resolve, reject)=>{resolve('123')})p1.then(resolve => {console.log(resolve);})p1.then(resolve => {console.log(resolve);})
Promise的链式调用
let p = new Promise((resolve, reject)=>{resolve('123')})p.then(value => {return new Promise((resolve, reject)=>{resolve('success')})}).then(value => {console.log(value);}).then(value => {console.log(value); //undefined 状态为成功,但是因为上面没有返回值 所以返回值为undefined}).then(value => {console.log(value); //undefined})
promise异常穿透现象
用于then的链式调用,在最后放一个.catch就可以了不管是哪一步发生失败,都交由最后的catch处理let p = new Promise((resolve, reject)=>{resolve('123')})p.then(value => {return new Promise((resolve, reject)=>{resolve('success')})}).then(value => {console.log(value);}).then(value => {console.log(value);throw '出错啦'}).then(value => {console.log(value);}).catch(reason => {console.log(reason);})
中断promise链
有且只有一种方式,只有返回一个pending状态的promise对象因为状态没有改变,所以后面的then执行不了let p = new Promise((resolve, reject)=>{resolve('123')})p.then(value => {return new Promise((resolve, reject)=>{resolve('success')})}).then(value => {console.log(value);}).then(value => {return new Promise(()=>{})}).then(value => {console.log(value);}).catch(reason => {console.log(reason);})
async和await
async是协同Promise工作的,放置在函数前面,返回一个Promise对象,关键词await可以让JavaScript进行等待,直到一个promise执行并返回它的结果,JavaScript才会继续往下执行,await只能在async定义的函数内部执行。
async声明异步函数await会阻塞后面代码的执行如果返回的是reject 则返回错误信息。后面代码不执行
async
async function main() {// 如果返回值是一个非Promise类型的数据,那么返回的就是一个成功的Promise对象,并且你返回的值是什么,PromiseResoult的值就是什么return 521;// 如果返回的是一个Promise 的对象,根据Promise的返回结果来判断,如果是resolve就是成功的,如果是reject就是失败的、return new Promise((resolve, reject)=>{reject('error')})// 如果是抛出异常,则Pormise状态为失败,并且返回值就是抛出异常的值throw 'error'}
await
1、await右侧的表达式一般为Promise对象,但也可以是其他值2、如果表达式是promise对象,await返回的是promise成功的值3、如果表达式是其他值,直接将此值作为await的返回值注意:1、await必须写在async函数中,但async函数中可以没有await2、如果await的promise失败了,就会抛出异常,需要通过try...catch捕获处理
进程和线程
进程:就是在内存中正在运行的程序就叫一个进程 特点:在内存中独享一份空间
进程负责为程序的运行提供必备的环境(相当于工厂中的车间)
线程:一个应用程序是由多个线程组成,每一个线程之间是相互独立的
线程是计算机中最小的计算单位,负责执行进程中的程序
js是一个单线程 如果遇到耗时任务,而且同步,就会造成线程阻塞
/* 同步的代码 线程被阻塞了 */console.log(1);alert("http")console.log(2)
/* 回调函数处理耗时操作 *//* 异步 */console.log(1)setTimeout(()=>{console.log("http")},1000)console.log(2)
