ES6 - 同步与异步 / 初识Promise

同步与异步 / 初识Promise

javaScript 是一个单线程的语言

同步与异步

同步和异步是一种消息通知机制
只限于理解,不用于回答
同步:上一件事结束,才能去做下一件事
异步:上一件事没有做完,就可以做下一件事

  • 同步阻塞
    A调用B,B处理获得结果,A在过程中,一直等待B的处理结果
    没有拿到结果之前,需要A一直等待,直到拿到结果,然后才会继续执行

	let a = 10;
    function fn(){
		a = 20;
	}
	fn();
	console.log(a);
	
  • 异步非阻塞
    事件,定时器,网络请求
    A调用B,无需等待B的结果
    B通过状态通知、回调等方式在完成后,通知B

	let b = 20;
	// 定时器为 异步
    setTimeout(()=>{
	    b = 30;
	},2000)
	console.log(b)
	
	let c = 10;
    let img = new Image();
	img.src = "http://img.mp.itc.cn/upload/20170213/cb5d90c0ab244b319ff1739ec3f5ec92_th.jpeg";
	// onload 事件为 异步
    img.onload = function(){
		c = 20;
	}
    console.log(c) // =>(图片在加载同时)拿到 c 的原先数据 10 
    

Promise基础

Promise对象 不是解决了异步的问题,而是改变了异步的写法
会自带返回值,返回一个对象

内部状态
  • pending 等待中 ( 异步执行中 )
  • fulilled( 实际上是该状态 )
    resolved( 调用 ) 执行成功 调用 ---- resolve之后改变
  • rejected 执行失败 ---- 调用reject 之后改变

    let p = new Promise(function(resolve,reject){
		// this 是在匿名函数中 指向window
		console.log(this);  
		console.log(1);
		// resolve 调用表示当前执行成功,then 中的 函数1 开始执行
        // resolve("给then的数据");

		// reject 调用表示当前执行失败,then 中的 函数2 开始执行
        reject("失败的数据");
	});
	

new Promise( promise的回调函数,在实例化的时候可以直接执行 )

  • resolve( 传递参数给 执行成功后触发的函数 )
    代表异步执行完成,并成功拿到结果 ---- 将 promise对象 的状态改为 resolve
  • reject( 传递参数给执行失败后 触发的函数 )
    代表异步执行完成,但没有拿到结果 ---- 将promise对象的状态改为reject
  • resolve / reject 两种情况 二存一
then 方法

自带两个函数
promise.then( onFulfilled , onRejected )


    p.then(function(res){
    	// this 指向 window  ( this 存在于传递进来的匿名函数中)
		console.log(this) 
        //  res 接收的是 resolve(); 传过来的参数
        // resolve 调用后 console.log 才会执行
        console.log( res+ "异步处理结束后的结果");
	},function(rej){
		//  rej 接收的是 reject(); 传过来的参数
        // reject 调用后 console.log 才会执行
        console.log(rej + "执行失败");
	})

	console.log(p)
	
then链式写法
    let q = new Promise((resolve,reject)=>{
            resolve(2);
	});
    
    // q1 接收的是q的返回的
	let q1 = q.then((data) =>{
    	console.log("resolve");
		return new Promise((resolve,reject) =>{
        	// 调用对象 决定 返回的Promise状态
            // reject("emm")
            resolve("emmm")
		})
	},(data)=>{
		console.log("reject");
		return {
			n : 13
		}
	});	
	
	// q 的返回的 调用then 的变化
	q1.then((data) =>{
		console.log("q1的resolve")
	},(data)=>{
		console.log("q1的reject")
	});
	

then 方法会返回一个新的Promise对象
新的 Promise 对象状态

  • 默认情况:返回的是一个状态为 resolve 的Promise对象
  • 当then 的回调函数 返回的是一个 非Promise对象
    then 返回的是一个状态为 resolve(执行成功) 的Promise对象
  • 当then方法 返回一个 Promise 对象时,
    then的返回值也会变为 该状态的Promise对象

Promise动画示例

前端HTML准备
	
	<style>
        *{
            margin: 0px;
            padding: 0px;
        }
        #box{
            width: 100px;
            height: 100px;
            background: purple;
            border-radius: 50%;
            position: absolute;
        }
    style>
	<div id="box">div>
	
前端JS代码

	/*
		el      元素
        attr    样式
        val     目标样式 具体值
        cb      当前动画结束要做的事情
    */ 
	function move(el,attr,val){
	    // 当前值
        let now = parseFloat(getComputedStyle(el)[attr]);            
        // 方向
        let speed = (val - now) / Math.abs(val - now) *2;
        return new Promise((resolve) => {
        	clearInterval(el.timer)
        	// 绑给元素 el.timer
        	el.timer = setInterval(()=>{
	        	if (Math.abs(now - val) <= 0) {
	            	clearInterval(el.timer);
                	resolve();
				}else{
			        now += speed;
		            el.style[attr] = now + "px";
				}
			},20);
		});
	}
	{
		let box = document.querySelector("#box");
		// 使用Promise 来完成回调
		function boxMove(){
	        move(box,"left",150).then(()=>{
            	// 覆盖本应该返回的 Promise 对象
                return move(box,"top",150);
			}).then(()=>{
	            return move(box,"left",0);
	        }).then(()=>{
	            return move(box,"top",0);
            }).then(()=>{
	            // 回调 不停地循环
                boxMove()
			})
		}
        boxMove();
	}
	

你可能感兴趣的:(es6)