1.为什么要使用回调函数?
当我们的请求既有异步,又有同步的时候,如果异步请求在同步请求的上方,异步请求比较慢,要先等待异步请求执行完再去执行同步请求,比较耗时。这时候我们将异步请求放在一个回调函数里,就不必等待异步请求执行完再去执行同步请求。
其实使用回调函数最终目的是为了获得外层普通函数(同步请求)的执行结果res,使用箭头函数的最终目的是为了获得上一个回调函数的执行结果res.
2.为什么使用promise呢?
在一段代码中,如果有两个异步请求,例如有两个回调函数,我们想让第一个函数(代码在上方)执行完成之后,得到一个结果,再去执行第二个函数(代码在下方)
由于异步请求的执行不一定是按照代码从上到下的顺序执行的,因此程序有可能先执行第二个函数,再去执行第一个函数,这样就会报错。为了解决这个问题,传统的方法
是将第二个回调函数嵌套在第一个回调函数内部,就可以保证第一个回调函数执行完成后再执行第二个回调函数。但是问题又来了,如果一段代码中有多个回调函数,就要不停的嵌套,就会进入回调地狱,这时候promise就派上用场了。
有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
promise可以使用.then(res)=>{函数体}的方式,将上一个函数返回结果res作为参数传递到下一个回调函数中去,这样就能保证上一个函数执行完成之后,再执行下一个函数。其中axios就是基于promise的。
qpromise()
.then((res)=>{
//code
return res.a;
})
.then((res)=>{
//code
return res.b;
})
.then((res)=>{
//code
return res.c;
})
采用链式写法,即then后在调用另一个then方法
3.
ES6规定,Promise 对象是一个构造函数,用来生成Promise 实例。
下面的代码就是一个Promise 实例:
var promise=new Promise(function(resolve,reject){ //code if(/*异步操作*/){ resolve(); }else{ reject(); } })
Promise构造函数接受一个函数作为参数,该函数有两个参数分别是resolve和reject,它们也是函数。
resolve函数的作用是,将Promise 对象的状态从“未完成”(pending)==>“成功”(resolved),在异步操作成功时调用,并将异步操作结果,作为参数传递出去。
reject函数的作用是,将Promise 对象的状态从“未完成”(pending)==>“失败”(rejected),再异步操作失败时调用,并将操作报错的错误,作为参数传递出去。
3.紧接着问题又来了,这样还是会产生很多回调函数,要不停的.then(()=>{ }),现在async和await就派上用场了,它可以让异步方法执行的顺序依据我们的需求而定,两者是结合使用的,await后面跟的是promise实例,
也就是说,async,await和promise三者必须连用。
例如我们现在有两个promise实例,
那么我们会先执行fnPromise1(),再执行fnPromise2(),虽然fnPromise1()是在3秒之后执行,fnPromise2()是在2秒之后执行,按理说应该先执行fnPromise2(),但是由于我们用了await,就相当于同步,先执行第一个await,再执行第二个await. await要放在异步方法里面使用,和promise或者async结合使用。无论是使用箭头函数,还是使用await,最终结果都是获得promise.