promise-async-await

  异步就是比较耗时的操做,CPU缓存的速度是最快的,而后是内存,而后是硬盘,因此从硬盘上读取文件是很是慢的,js认为从硬盘上读取文件是一个异步操做;另一种是网络请求,这种也是异步的;操做dom节点也是很是耗时的,但倒是同步操做,由于做为异步来处理比较麻烦。node

  promise就是一个承诺,在js中就是承诺过段时间会返回一个结果,而这个过段时间就指的是异步操做。webpack

  promise本质上是一个有限状态机,状态机指的是根据特定的条件按照必定的顺序进行转换,并且过程不可逆。每一个promise实例都有三种状态:pending、resolve、reject。在状态机中,须要某些条件才能将本身的状态触发。git

  状态只有两种:从初始状态到成功:pending->resolve;从初始状态到失败:pending->reject。promise实例状态机状态的变化会触发promise原型上的then或catch方法的执行github

  DOM规范是运行在浏览器上的规范,好比navigator,只在dom上有,在node上没有;而ECMAScript规范,不只在浏览器中可使用,也能够在node.js中使用。web

如何构建一个promiseajax

  构建一个promise实例须要给promise构造函数传入一个有两个形参的函数,第一个形参运行后会让promise实例处于resolve状态,因此通常用resove表示成功状态;第二个形参运行后会让promise实例处于reject状态,因此通常用reject表示失败状态。new出来的promise实例,有两个方法(then,catch,then捕获成功的操做,catch捕获失败的操做。),而且能够链式调用。在使用的时候,要将then放在catch的上面,这是由于then里的错误也能够在catch中捕获到,如代码所示:json

let promiseInstance = new Promise((resolve,reject) =>{ setTimeOut(() => { resolve('this is resolve.') }) }) promiseInstance .then((value)=>{console.log(value)}).catch((err)=>{console.error(err)})

    promise是处理异步的,而网络请求是异步最多见的场景,因此能够用promise封装一个网络请求的方法,因此不少时候promise的实例是做为函数的返回值是,调用函数后能够对返回值的Promise对象进行相应的操做api

function ajaxPromise(){
  return new Promise((resolve,reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open('get',queryUrl,true);
    xhr.send(null);
    xhr.onReadyStatechange = () => {
      if(xhr.readyState === 4){
        if(xhr.status === 200){
          resolve(xhr.responseText);
        }else{
          reject(xhr.responseText)
        }
      }
    }
  }) }

ajaxPromise('http://api.github.com/')
.then((value) => {
  console.log(value);
})
.catch((err) => {
  console.error(err)
})

then与catch的使用promise

  状态机的状态是不可逆的,因此执行了resolve方法,就算再执行reject方法,也不会有效果了。浏览器

promise的api

  promise实例上的方法

    promise.prototype.then()

    promise.prototype.catch()

  promise构造函数上的方法

    promise.all(Array) 返回一个promise,等待参数中全部的promise都处于resolve状态后会触发返回的promise实例的resolve状态

    promise.race(Array) 返回一个promise,参数中第一个执行完成的状态决定出发哪一个函数

    promise.resolve() 马上返回一个resolve状态的实例

    promise.reject() 马上返回一个reject状态的实例

let promise1 = new Promise((resolve,reject)=>{ setTimeout(resolve,1000,'success1') }) let promise2 = new Promise((resolve,reject)=>{ setTimeout(resolve,1000,'success12') }) let promise3 = new Promise((resolve,reject)=>{ setTimeout(resolve,1000,'success3') }) Promise.all([promise1, promise2, promise3]).then((value)=>{ console.log(value) }).catch((err)=>{ console.error(err) })

tips:setTimeOut的第三个参数,是第一个函数参数执行的时候,要传入的参数

promise.then的执行时机

  promise.resolve是处理异步问题的,因此会先把同步的代码执行完,再执行promise.resolve返回实例的then或catch的代码

  而Promise构造函数是同步的,then方法是异步的。setTimeOut的执行时机是最晚的

promise并非处理异步最好的方法,好比回调金字塔的问题并无解决,只是看起来更清晰了。解决异步最好的方法是async

generator

  有点像一个函数内部有多个函数,是一个状态机,yield生成

function* genFunc(){   yield 'hello';
  yield 'generator';
  yield '!'
  return 'end'//generator不建议使用return
}

 generator返回的不是返回值,也不是一个生成的内容,而是一个迭代器,迭代器是一个可遍历的对象,迭代器有个next方法。经过for-of循环遍历迭代器

连续运行的generator

function* genFunc(initValue){   let first = yield new Promise((resolve,reject)=>{     setTimeOut(resolve,1000,'1'+initValue)   })   let second = yield new Promise((resolve,reject)=>{     setTimeOut(resolve,1000,'2-'+first)   })   let third = yield new Promise((resolve,reject)=>{     setTimeOut(resolve,1000,'3-'+second)   })   let genHandler = genFunc(1)   genHandler.next().value.   then((value) => {     genHandler.next(value).value.     then((value) => {       then((value) => {         console.log(value);       })     })   }) } 

co库与async函数

  import co from 'co'

  上述代码中依然有回调金字塔,能够用co库解决

co(genFunc(1)).then((value) => {console.log(value)})//2-11

  async至关因而generator+promise+co,是es7的新语法,目前没有浏览器实现,因此须要用webpack+babel编译一下才能够运行。

 

 

如何同步异步请求,即两次请求,异步执行,如何在两次请求都执行完成的状况下执行后续程序

function request(content){ setTimeout(()=>{ document.body.append(content) },Math.floor(Math.random()*1000)) //时间控制为不肯定
} request('hello') request('world') //如何在两次request完成后执行代码。可使用promise.all,只要两个异步有一个完成就能够,可使用promise.race
docuement.body.append('finished')

如何处理回调嵌套回调

//珠峰课堂是先去服务端拿取token,而后再去拿课程
fetch('https://ketang.zhufengpeixun.cn/token') .then(response => { response.json().then(tokenJson =>{ const token = tokenJson fetch('https:ketang.zhufengpeixun.cn/course') .then( response =>{ response.json().then(tokenJson =>{ } }) }) })

promise定义:用于异步计算,表明一个当前、将来或永远不可用的值  

//promise中的代码段被直接执行了
const promise = new Promise((resolve,reject){ document.body.append('hello') }) const a = () =>{ document.body.append('world') } a(); //执行结果是hello world
//用promise表示一个将来的值
function resolve_example(){ const promise = new Promise((resolve,reject)=>{ document.body.append('start.....'); setTimeout(()=>{//promise表明了一个将来值
        resolve('done') },2000) }) return promise; } const promise = resolve_example(); //获得一个将来完成的值,此处data是异步返回的部分
promise.then(data => { document.body.append(data) })

 

promise有三种状态,当被new出来的时候属于pending状态,使用resolve则是fulfill状态,使用reject则是fail状态

Executor是构造Promise的惟一参数,在promise构造的时候会被立刻执行

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息