异步(promise)

94 阅读3分钟

回调函数与异步

为什么要有异步

js是单线程,为了不浪费时间,提高运行效率。

异步工作原理

主要是依据settimeout(定时执行回调函数)和setinterval(定时执行回调函数并以相同间隔重复执行,可以通过clearInterval取消重复)函数。

js有一个专门处理计时器的模块。js主线程先解决同步任务,与此同时,计时器模块独立运行,将到时的任务放入异步队列,当同步任务解决完以后,js会解决到时的异步队列。

settimeout和setinterval实际执行时间

真正实行时间会比与设定时间久,因为需要等同步队列以及前面的异步队列执行完再执行。

为什么要用回调

js遇到回调函数即会放入异步队列。

回调正是确保一段代码执行完毕之后再执行另一段代码的方式,可以确保函数异步执行。

回调函数优点:不会立即执行、是个闭包(可以访问到到其外层定义的变量)

promise

为什么要用promise

为了保证异步调用的函数之间保持顺序(因为是按照解析速度,谁快谁先放入异步队列,顺序不一定按照代码顺序),因此需要在一个异步函数里的回调函数参数位置放入另一个异步函数(即需要多次嵌套)

宏队列与微队列

在执行完同步代码后,js会执行轮询微队列,在轮询宏队列【主线程内代码要先完成再轮询,就是一份份代码完成后再按顺序找新的】(例如在微任务在宏任务内时,他的状态没创建出来时,微任务没有加入微队列时,微任务次序后于宏任务)【状态转变才会产生微任务!!!】

promise状态

pending(初始状态,准备状态)

resolve(成功)

reject(失败)

状态改变一次后就不会再更改,改变后立即放入微队列内

语法

new Promise((resolve,reject)=>{
	//同步代码

	//更改状态,只能更改一次,更改后无法再次更改
	//resolve('成功');
	//reject('失败');

	//更改完状态再将相应代码放入微队列,等待同步代码执行完后再执行
	//promise和then是对应出现的,then返回的也是promise对象
	//then可以一直套用下去,并且then中任务能确保异步的顺序
}).then('成功代码','失败代码');

返回值

返回一个带状态的primose,可以作为下一个promise的参数

此时状态改变遵循参数的状态而不是调用的

let p1 = new Promise(( resolve, reject)→{
	reject("拒绝");
});

new Promise(( resolve, reject) →{ 
	resolve(p1);//即遵循p1而不是resolve
} ). then(
msg→{
console. log(msg);
},
error→{
console. log(error+'error');
})
//拒绝error

promise.prototype.then()

  • 作用是为promise实例添加状态改变时的回调函数
  1. 接收两个函数作为参数,分别代表fulfilled(成功)和rejected(失败),失败函数可选
  2. then()返回一个新的Promise实例,所以它可以链式调用
  3. then()默认返回一个状态为成功的新的Promise实例
  4. 当前面的Promise状态改变时,.then()根据其最终状态,选择特定的状态响应函数执行
  5. 状态响应函数可以返回新的promise,或其他值,不返回值也可以我们可以认为它返回了一个null;
  6. 如果返回新的promise,那么下一级.then()会在新的promise状态改变之后执行
  7. 如果返回其他任何值,则会立即执行下一级.then()

嵌套返回

.then(
  value > {
    return new Promise((resolve,reject) = {//其后的then是对该返回值promise的处理
    	reject( "处理失败" );
    })
.then(
null, 
r =console.log(r);
});
//处理失败

promise.all

该方法用于多个promise实例,包装成一个新的promise实例

var p = Promise.all([p1,p2,p3]);

  • p1,p2,p3之间呈&&关系
  • promise.all返回值是一个数组,包含了p1,p2,p3的返回值
Promise.all([p1, p2]).then((result) => {
  console.log(result)               //['成功了', 'success']
}).catch((error) => {
  console.log(error)
})