* promise承诺 * 解决js中异步编程的问题 * * 异步-同步 * 阻塞-无阻塞 * * 同步和异步的区别? 异步;同步 指的是被请求者 解析:被请求者(该事情的处理者)在处理完事情的时候的通知机制。 异步:当事情处理完成后被请求者会发信息通知请求者该事情处理完成。在这期间被请求者能够选择是继续等待命令请求完成仍是去作其余事等待被请求者返回。 同步:当事情处理完成后被请求者不会告知请求者,等到请求者发来询问是才会告知 阻塞;非阻塞 指的是请求者 阻塞:针对请求者来讲的,委托其余人处理一些事情的时候,被请求者是等待请求处理完成仍是继续向下执行其余任务。阻塞就是等待事情完成才继续执行 非阻塞:针对请求者来讲,请求者委托被请求者处理一些事情时不等被请求者答案先去作其余事,而且每隔一段时间询问被请求者该事件是否完成。 js采用的是异步非阻塞模式。 promise 是一个构造函数(在何时要用promise当咱们进行一些操做须要同步进行时) 经过new promise进行调用 Promise: * 构造函数 * new Promise(callback) * callback: 要异步处理的任务 经过Promise构造函数获得一个Promise对象,咱们传入的callback将会被Promise对象所执行 * Promise会维护一个任务状态,这个状态是一个Promise内部的属性 * [[PromiseStatus]] * 该属性一共有三个值 * 1. pending : 正在处理,Promise对象一旦被建立就会更改成该状态,他是默认值 * 2. resolved : 处理完成 * 3. rejected : 处理失败 * resolved,rejected这两个状态是须要靠咱们手动去维护的。由于异步任务的结果是成功仍是失败,是由咱们的具体业务所决定的,Promise对象是没有办法肯定的。
web
咱们须要在咱们业务处理中,去根据实际状况改变Promise对象的状态 * 改变Promise状态 * 当咱们把一个callback函数传递给Promise对象的时候,Promise对象会去执行该callback函数,同时,还会传递两个参数给这个callback,因此,咱们能够在callback函数接收这两个参数 * 这两个参数都是一个函数 * resolve * 当咱们调用该函数的时候,会把当前的Promise对象的状态改为resolved * reject * 当咱们调用该函数的时候,会把当前的Promise对象的状态改为rejected * * Promise对象还有一个方法:then * 该方法接收两个参数,这两个参数都是callback函数,这两个callback不会当即执行,当Promise的状态一旦发生改变就会执行then方法中传入的函数,有点相似事件绑定 * 当Promise状态变成resolved,那么执行then的第一个参数callback * 当Promise状态变成rejected,那么执行then的第二个参数callback 举列:如今咱们有一个延时定时器setTimeout 以下 var a=10; setTimeout(()=>{ a+=10; },1000); console.log(a);//此时a打印出来为10 由于在js为异步非阻塞的语言 在延时定时器中的函数尚未执行的时候下面的console.log就已经执行完毕因此打印出来为10 。 那么咱们想获得延时定时器处理后的值能够这么作。 var a=10; var p1=new Promise((resolve,reject)=>{ setTimeout(()=>{ a+=10; resolve(err)//处理完成 },1000);//只有当处理完成以后才会执行then中的函数 此时resolve()中的东西为then的传参。 }) p1.then(()=>{ console.log(a) }); 此时打印出来的就是20.
then方法如何传递数据 * 咱们能够经过resolve,reject方法来传递数据 * 咱们只要在调用上面两个函数的时候,把须要传递给后续的then方法的数据做为其参数就能够 * catch也是相似catch方法就是捕获在promise的then中又传递了promise这样多个嵌套的话 拿 then 的 方法来监听太过繁琐 catch 监听 主要有一个执行错误就会被catch捕获从而执行catch中的函数 * */ new Promise((resolve, reject) => { let b = 10; setTimeout(() => { b += 10; resolve(b); // reject('第一个任务出错了'); }, 1000); }).then(function(b) { console.log(b); return new Promise((resolve, reject) => { setTimeout(() => { b *= 2; resolve(b); // reject('第二个任务出错了'); }, 1000); }); }).then(function(b) { console.log(b); return new Promise((resolve, reject) => { setTimeout(() => { b *= b; resolve(b); reject('第三个任务出错了'); }, 1000); }); }).then(function(b) { console.log(b); }).catch(function(err) { console.log(err); });
有的时候在一个Promise任务中须要处理多个异步任务,那这多个异步的任务是同时执行的,可是执行时间有是不肯定的。后续的任务须要这几个异步任务所有完成之后再执行,那么就须要用到Promise中提供的all方法来实现
var p1 = new Promise((resolve, reject) => { let a = 1; setTimeout(() => { a++;
// reject('one'); resolve(a); }, Math.random() * 1000); });编程
var p2 = new Promise((resolve, reject) => { let b = 2; setTimeout(() => { b++; resolve(b); }, Math.random() * 1000); }); /* * 把两个不一样的异步任务分别包装在一个Promise对象中,而后调用Promise对象静态方法all,把上面多个不一样异步Promise做为数组传递给all方法的参数 * 这个时候Promise.all方法中会维护一个状态,这个状态是根据传入的多个异步任务的状态共同决定的 * 当多个异步任务的状态都变成了resolved,那么all的状态才是resolved,可是只要有一个异步任务的状态变成了rejected,那么all的状态就会变成rejected * */ p1 p2 是两个promise 在下面的方法中只有当p1 p2 都为resolved的时候才会执行下面的函数方法 Promise.all([p1, p2]).then(([a, b]) => { console.log(a, b); }).catch((err) => { console.log(err); })
await async 是es7 定义的新标准 经过 async 声明一个异步函数在该函数中 async function(){ await fn1 //这个fn1 表明一个函数 await fn2//这样的话在fn1 执行完成以后才会执行fn2 }