javascript中的箭头函数和Promise对象

Promise新建后就会立即执行!!!

一、箭头函数

箭头函数 是在es6 中添加的一种规范。

x => x * x 相当于 function(x){return x*x}

x => x * x 
//相当于
function(x)
{
    return x*x
}

箭头函数相当于 匿名函数, 简化了函数的定义。 语言的发展都是倾向于简洁 对人类友好的, 减轻工作量的。

// 两个参数返回后面的值
(x, y) =>x*y + y*y
//没有参数
() => 999
// 可变参数
(x, y, ...rest) =>{
    var i,sum = x+y;
    for (i=0;i<rest.length;i++){
        sum += rest[i];
    }
    return sum;
}

如果要返回一个单对象, 就要注意, 如果是单表达式,第一种会报错, 要使用第二种方式。

// 这样写会出错
x => {foo:x} // 这和函数体{}有冲突
// 写成这种
x => {{foo:x}}

使用案例:

var sum = (x,y)=>{
		    console.log("箭头函数内部");
			return x+y;
}
console.log("sum res:"+sum(5,6));

二、Promise对象(承诺)

js语言的执行环境是“单线程”。所谓单线程,就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务。

在实际的业务中,异步模式是非常重要的角色。我们可以有多种异步编程的方法,比如通过回调函数,但回调函数缺乏顺序性和可信任性。这个时候promise就很重要了。

1、Promise对象的两个特点

(1) 对象的状态不受外界影响。Promise 对象代表一个异步操作,有三种状态:

  • pending: 初始状态,进行中。
  • fulfilled: 已成功。
  • rejected: 已失败。

只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 对象的状态改变,只有两种可能:从 Pending 变为 Resolved 和从 Pending 变为 Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。

每一个异步任务返回一个promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成: f1().then(f2);

  1. 每个异步任务都将返回一个then对象。
  2. 每个then对象都有一个then函数可以带两个参数,一个success处理程序和error处理程序。
  3. then函数中的成功或错误处理程序将仅在之后调用一次异步任务完成。

2、Promise的优缺点

优点:

  • 可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
  • Promise 对象提供统一的接口,使得控制异步操作更加容易。

缺点:

  • 无法取消 Promise,一旦新建它就会立即执行,无法中途取消。
  • 如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。
  • 当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

2、基本用法

(1)Promise构造函数接受一个函数作为参数。该函数的两个参数分别是resolve和reject,它们是两个函数,由JavaScript引擎提供,不用自己部署。

  • resolve函数的作用:将Promise对象的状态从“Pending未完成” 变为 "Resolved成功",在异步操作成功时调用,并将异步操作的结果作为参数传递出去;
  • reject函数的作用:将Promise对象的状态从“Pending未完成” 变为 "Rejectd失败",在异步操作失败时调用,并将异步操作报出的错误作为参数传递出去;

实例1:

var promise = new Promise(function(resolve,reject){	
    
    //释放资源,关闭窗口等操作
    if(/*异步操作成功*/)	
    {
        resolve('success');
    }else{
        reject('failed');
    }
});

(2)Promise实例生成以后,可以用then方法分别指定Resolved状态和Rejected状态的回调函数。then方法接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为Resolved时调用,第二个回调函数是Promise对象的状态变为Rejected时调用。其中第二个函数是可选的,可以不提供。这两个函数都接受Promise对象传出的值作为参数。

实例2:

function main() {
      let promise =new Promise((resolve,reject)=>{
        for(var i=0;i<3;i++)
        {
          console.log("i:"+i);
        }
        if(i==3)
        {
          resolve(i);
        }else{
          reject(i);
        }
      });
      promise.then((value)=>{
        console.log("success:"+value);
      },()=>{
        console.log("failed:"+value);
      });
      console.log("test end");
}

实例2测试结果:

 Promise新建后就会立即执行。所以首先输出的是1~3。then方法指定的回调函数将在当前脚本所有同步任务执行完成后才会执行,所以“success:3”最后输出。

实例3:

//catch(failureCallback) 是 then(null, failureCallback) 的缩略形式。
//then() 函数会返回一个和原来不同的新的Promise2
var promise2 = promise.then(function(res){
	console.log(res);
}).catch(err=>{
    console.log(err);
})

3、链式调用

连续执行两个或者多个异步操作是一个常见的需求,在上一个操作执行成功之后,开始下一个的操作,并带着上一步操作所返回的结果。我们可以通过创造一个 Promise 链来实现这种需求。

new Promise((resolve, reject) => {
    console.log('初始化');

    resolve();
})
.then(() => {
    throw new Error('有哪里不对了');

    console.log('执行「这个」”');
})
.catch(() => {
    console.log('执行「那个」');
})
.then(() => {
    console.log('执行「这个」,无论前面发生了什么');
});

三、async和await关键字

案例一:

async function f1()
{
    return "abc";
    //相当于 return new Promise((resolve)=>{ resolve("abc")});

}

案例二:

function f1()
{
    return new Promise((resolve,reject)=>{ 
	setTimeout(()=>{resolve('success')},2000)
    });
	
}	

async function f5()
{
	var c = await f1();	
	console.log(c);
	console.log('aaa');//等待f1执行完之后再执行
}
f5();

案例三:

async function f1()
{
	return Promise.reject('sss');
}
      
async function f5()
{
	try{
		var c = await f1();	
	}catch(e){
		console.log(e);
	}
			
	console.log(c);//上面reject后,这行及以后的语句不会执行
	console.log('aaa');
}
f5();

案例四:await的返回值

如果await得到不是一个promise对象,那么就不会等待这个异步操作。

如果是一个promise对象,await就会等待promise对象的resolve,得到传入resolve的参数,作为返回值。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
曾经听许多前端从业者说:“前端发展太快了。”这里的快,十有八九是说层出不穷的新概念,余下的一二,大抵只是抒发一下心的苦闷罢——前两日刚习得的新技术转眼就“落后”——仔细品味这苦闷,除却不得不持续奔跑的无奈,更多的是一口气,一口卯足了劲儿也要把新知识全数揽入囊的不服气。作为刚入行的新人,对这点体会颇深。就像是蓦地从某个时间点切入,半数时间向前走,半数时间向后看,瞻前顾后,回味揣摩这十年间的岁月精魄,还得翘首盼着花花新世界,不时再问自己一句,这样走下去真的会好么?是的,其实答案人尽皆知,同时也无人知晓,因为没人能预言未来,顶多只能预测未来,但有一件事情永不会错,当你笃定地沿着一条路走下去,结果通常不会太糟糕,但凡能在浮躁的社会冷静下来潜心磨砺,多少总会有收获。幸而我有意弱化了对新信息的执念,开始做一些事情,《深入浅出ES6》就是其一件。 纵观整个系列,亦即纵观ECMAScript 2015的整个体系,吸取了诸多成功经验:借鉴自CoffeeScript的箭头函数;始于C++项目Xanadu,接着被E语言采用,后来分别于Python和JavaScript框架Dojo以Deferred对象的面貌出现的Promise规范(详见Async JavaScript一书3.1章);借鉴了C++、Java、C#以及Python等语言的for-of循环语句;部分借鉴Mustache、Nunjucks的模板字符串。 当然,新的语言体系也在之前的基础上查漏补缺:弥补块级作用域变量缺失的let和const关键字;弥补面向大型项目缺失的模块方案;标准委员会甚至为JavaScript增加了类特性,有关这一方面的特性褒贬不一,Douglas Crockford曾在2014年的Nordic.js大会发表了题为《The Better Parts》的演讲,重新阐述了他个人对于ECMAScript 6的看法,他认为Class特性是所有新标准最糟糕的创新(我个人也略赞同这一说法,类的加入虽然有助于其它语言的使用者开始使用JavaScript,但是却无法发挥出JavaScript原型继承的巨大优势);以及为了保持非侵入式弥补其它新特性而诞生的Symbols。 其它的新特性也相当诱人,熟练掌握可以大幅度提升开发效率:迭代器Iterator、生成器Generators、不定参数Rest、默认参数Default、解构Destructuring、生成器Generator、代理Proxy,以及几种新类型:Set、Map、WeakSet、WeakMap、集合Collection。 以上提及的新特性只是其的一部分,更多的新特性等待着大家进一步挖掘。整个系列的翻译历时150余天,坚持专栏翻译的日子艰苦也快乐,编辑徐川细心地帮我审校每一篇文章,编辑丁晓昀赠予钱歌川先生详解翻译之著作让我大开眼界,与李松峰老师的交流也让我深刻理解了“阅读、转换、表达”的奥义所在,最感谢我的母亲,在我遇到困难需要力量的时候永远支持着我。选择ES6作为前端生涯的切入点实之我幸,恰遇这样的机会让我可以一心一意地向前走,向未来走。我很敬佩在“洪荒”和“战乱”年代沉淀无数经 验的前辈们,你们在各种不确定的因素左右互搏,为终端用户提供统一的用户体验,直到如今你们依然孜孜不倦地吸取业内新鲜的经验。技术在进步,也为前端人 提供着无限的可能性,我们有责任也有义务去推动新标准的发展和普及,诚然在商业的大环境下我们不愿放弃每一寸用户的土壤,但携众人之力定将能推动用户终端 的革新。ES7标准的提案纷纷提上日程,用不了多久也将登上前端大舞台。也感谢午川同学友情提供译文《深入浅出ES6(十):集合 Collection》,让我在困难时期得以顺利过渡。最后祝愿国内前端社区向着更光明美好的未来蓬勃生长!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值