如何理解ES6的sleep和yield的异同

深入理解ES6 -- 函数 - CSDN博客
深入理解ES6 -- 函数
函数是所有编程语言的重要组成部分,在 ES6 出现前,JavaScript 的函数语法一直没有太大的变化 , 从而遗留了很多问题和隐晦的做法,导致一些基本功能经常要编写很多代码.例如定义一个类 要用到安全模式,做检测.函数默认参数如何赋值等问题.
1.函数形参的默认参数
JavaScript 函数有一个特别的地方,无论函数定义中声明了多少形参,都可以传入任意多个参数,由于这个原因,JavaScript函数有一个特殊的默认参数集合arguments,也是这个原因,JavaScript函数无法重载.这里讲述一下ES6 函数的默认参数的一些变化
在ES5 中使用默认参数常用方法
function func1( a , b){
a = a || 200;
b = b || "argus2";
在这个实例中,为默认参数 a,b 赋默认值,通常使用逻辑或来实现,看上去没有任何问题,但还是有些问题,例如你无法给 a 赋值为0, 0转化为Boolean值为false ,所以 a 的 值还是200,同理你也无法给b赋值为一个空字符串.
为了解决这个问题,可以通过强制类型检测来实现,这也是大多数框架实现默认值的方法
function func1(a,b){
a = (typeof a !=="undefined") ? a :200;
b = (typeof b !=="undefined") ? b :"argus2";
ES6 实现默认参数的形式
function func1(a = 200 , b = "argus2"){
可以为函数指定任意多个参数指定默认值,在已指定默认值 的参数后面可以继续声明无默认值的参数 例如:
function func1( a , b=200,c){
且只有传入undefined或不填的时候,才会使用默认参数
function func1(a ,b=200){
console.log(b);
func1(1,null);
使用参数默认值对 arguments
在ES5 中使用严格模式
arguments 只读 ,非严格模式下,可写.
在ES6中使用参数默认值后 ,arguments 会和ES5 的严格模式下保持一致 –& 只读,不可写
默认参数表达式
关于默认参数值有一个有趣的特性,非原始值传参,例如
function getValue(){
function add( first ,second = getValue()){
return first +
add 函数的第二个参数默认值为 getValue 函数的执行结果,但是getValue只有在第二个参数为默认参数的时候才会执行,并不会在声明的时候就执行,如果getValue()返回的是不同 值 , 就会出现 add (1);相同执行却返回不同值.
由于默认参数是在函数调用时求值,所以可以使用先定义的参数作为后定义的参数的默认值 ,例如:
function add(first ,second = first)
但是不能使用后定义的参数为先定义的参数的默认值,例如
function add(first = second,second){
return first +
add(undefined,1);
对于函数而言相当于执行
var first = first ||
var second =
处理无命名参数
在ES5 中有arguments ,无需定义每一个需要使用的参数.
在ES6 中 提供了不定参数
在函数的命名参数前添加三个点 (…)就表示这是一个不定参数,该参数为一个数组,包括着自它传入之后的所有参数,不定参数在函数定义中只能拥有一个,且必须作为最后一个参数,反过来,这其实就是解构赋值中的数组解构. 使用方法和规则一致
function func1(first,...argus){
console.log(argus);
func1(1,1,2,3,4);
let [first,...others] = [ 1, 1,2,3,4];
console.log(others);
ES6 中所有的函数的name 都有一个合适的值,直接定义的函数,name 属性值为函数名,
name 属性的特殊值,
var person = {
get firstName(){
return "Nicholas";
sayName:function(){
console.log(this.name);
console.log(person.sayName.name);
console.log(person.firstName.name);
getter 和 setter 函数的name 属性会被加上前缀 get set,
通过bind 函数创建的函数其名称会添加”bound” 前缀 ,而通过Function构造函数创建的函数,其前缀 会添加 “anonymous”
明确函数的多重用途
在ES5中定义一个类 实际就是声明一个函数 ,使用new 关键词调用来实现,这样函数和类的双重身份会让人感到混乱.
JavaScript 函数有两个不同的内部方法 call 和construct,通过函数调用时,执行的是call ,而通过new 新建对象执行的是construct,拥有construct的内置方法的函数 ,称之为构造函数,由于不是所有的函数都有construct方法 ,例如箭头函数就没有.
在ES5 中为了安全的使用类 ,一般会使用一个称之为安全模式的方法
function Person(name,age){
if(this instanceof Person){
this.name =
this.age =
return new Person(name,age);
var person = new Person("lucy",20);
var person1 = Person("jack",21);
上述感觉可以解决函数是否只能被当做类调用的问题,但是有两种不依赖new 关键字就可以将this 绑定到person上面的实例,call 和apply,
var person = new Person("Jack",20);
var notPerson = Person.call(person,"Michale");
所以ES6 上做了些改进
元属性 new.target
为了解决这个问题,引入了new.target 这个元属性 , 当调用函数的 construct方法时,new.target被赋值为 new 操作符的目标.通常是新创建的对象实例,也就是函数体内this的构造函数,通过其他方式(call)调用的,则new.target 的值为
function Person(name,age){
if(new.target !=="undefined"){
this.name =
this.age =
console.error("必须通过new 关键词调用");
这样就解决了 通过call 和apply 来绑定this 的问题.
注意 new.target 只能在函数里面调用.
在ES6 中函数引入了一个有趣的新特性,箭头函数,箭头函数是一种使用箭头(=&)定义的新语法,与传统函数有些许不同
没有this,super,arguments 和new.target绑定,箭头函数中的这些值都是由外围最近一层的非箭头函数决定的.
不能通过new 关键字调用,也就是说箭头函数没有内置 construct 方法
没有原型,不能通过new 关键字调用,就不能成为构建原型的需求,所以 没有prototype 属性. 不能被定义为一个类,一个纯粹的函数
不可以改变this 的绑定,函数里面this 值不可改变,始终保持一致
不支持arguments对象 ,但是可以通过不定参数和默认参数来访问参数列表,
不支持重复的命名参数
箭头函数的语法
var add = function(a,b){
var add1 = (a,b)=&a+b;
箭头函数的参数 为 =&左边括号的内容,右边为返回值.
当参数为一个的 时候()可以省略,当参数大于一个或者无参数时 “()” 是必须的.右边的为返回值,当返回的是一个对象时,返回值需要添加括号
//返回值为对象,需要添加括号
var createObj = ()=&({ name:"Jack",age:20 };
//复杂运算
var max = (a,b)=&{
//上述可以简写为 var max = (a,b)=&a&b?a:b;
箭头函数没有this 绑定 ,很多时候为了调用最外层的this,在函数中会使用 一个变量来存储 this 值,或者使用bind(this),来解决这个问题.
let PageHandler = {
id : "12345",
init : function(){
document.addEventListener("click",(function(event){
this.doSomething(event.type);
}).bind(this),false);
doSomething:function(){
console.log(this.id);
let PageHandler = {
id : "12345",
init : function(){
document.addEventListener("click",event=&this.doSomething(event.type),false);
doSomething:function(){
console.log(this.id);
箭头函数的语法很简洁,配合数组处理非常好用
例如排序,过滤等
var arr = [3,4,1,4];
arr.sort((a,b)=&a-b);//排序
arr.filter(a =& a&3);//过滤
//还可以串联起来
var arr1 = [3,4,1,4];
arr1.sort((a,b)=&a-b).filter(a=&a&4);//[1,3]
由于箭头函数没有this绑定,所以使用call 或者apply 都无法改变箭头函数的this 引用.
尾调用优化
尾调用优化是ES6引擎的优化, 之前的循环调用中,每一个未用完的栈帧都会被保存在内存中,当调用栈变得过大时.程序会出现问题,例如爆栈.
尾调用优化没有明确的语法,而是符合条件会自动优化,
1.严格模式下
2.尾调用不访问当前栈的变量(函数不能是一个闭包)
3.在函数内部,尾调用是最后一条语句
4.尾调用的结果作为函数值返回.
无法优化的示例
"use strict"
function doSomething(){
var Result = doSomethingElse();
function doSomething2(){
var sum =1;
fun = () =&
return func();
尾调用优化 和函数的懒执行有异曲同工之妙,典型的案例就是斐波拉契数列. 把 时间复杂度从 N^2 下降到N.
本人才疏学浅,如有错漏,欢迎大家留言指正.讲解不周到之处也希望能和大家一起学习进步.
本文已收录于以下专栏:
相关文章推荐
ES6中新增了箭头函数这种语法,箭头函数以其简洁性和方便获取this的特性,俘获了大批粉丝儿
它也可能是面试中的宠儿, 我们关键要搞清楚 箭头函数和普通函数中的this
一针见血式总结:
简要介绍:箭头函数中的this,指向与一般function定义的函数不同,比较容易绕晕,箭头函数this的定义:箭头函数中的this是在定义函数的时候绑定,而不是在执行函数的时候绑定。1、何为定义时绑...
对ES6Generator函数的理解什么是Generator函数
Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
简单说Generator函数是...
几个月前写过一篇博客,讲Generator,比较基础。最近总在写ES6,想深入讲讲yield的执行顺序。你可能想问,Generator执行顺序很简单啊,就是调用next()就执行下一个yield后面的...
简介:从根本上来说,JSX语法提供了一种创建React元素的语法糖,JSX语句可以编译成:
React.createElement(component, props, …children)的形式,比...
“深入理解ES6”是一个针对第6版ECMAScript(简称ES6)标准的新特性的系列教程。非常高兴能发布今天的内容。今天我们叫讨论ES6中最“奇妙”的特性。为什么说“奇妙”呢?首先,这个特性与已存在...
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
先看下代码:
function wrapper(generatorFunction) {
return function (...args) {
let generatorObject = generatorFunction(...args);
generatorObject.next();
return generatorO
const wrapped = wrapper(function* () {
console.log(`First input: ${yield}`);
return 'DONE';
wrapped().next('hello!')
// First input: hello!
这个输出结果怎么理解呢?想了半天不理解他的运行结果。还有下面代码:
function* dataConsumer() {
console.log('Started');
console.log(`1. ${yield}`);
console.log(`2. ${yield}`);
return 'result';
let genObj = dataConsumer();
genObj.next();
// Started
genObj.next('a')
genObj.next('b')
还是看不懂,求大神帮忙分析上述两段代码,帮我学习Generator函数。谢谢了。
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
yield 关键字有两个作用:
暂停生成器函数执行并返回后方表达式的值
恢复生成器函数执行并得到 next 方法传入的可选参数
你给到的两个例子都是用 yield 接收了 next 方法传入的参数。
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
生成器函数中使用yield就能表示异步了?我只了解迭代器的用法(跟python很像),关于为什么这样写就表示异步,实在没想明白。感觉只是让生成器函数的执行可以停在yield的地方?不知道怎么理解才对,请大神解释下~
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
生成器函数中的yield语句只是把控制权转移到了调用者,并不一定是异步的 -- 如果调用者在同一个tick中将控制权转回到生成器函数那肯定还是同步的;而对应的,如果使用 co 这种异步执行的调用者,则就能异步执行了。
具体原理你可以直接查看 co 的源代码。或者很多大神已经分析过了,比如参考以下两篇文章:
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
使用yield不表示异步啊.Async/await 才是吧.
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:前端在线资源
本文地址:
一、Promise是一种形式
春节假期看了一部电影,《超人-钢铁之躯》,我媳妇没睡着,说明这部电影还不错。其中有句台词印象深刻:“对于没有见过的东西,人会排斥,因为内心会恐惧”。
于是,就有这样一个问题出来了,如果让人快速接受一个新鲜未知、可能会排斥、带来恐惧的东西。
“介绍其强大以及厉害之处?”
比如本文要介绍的Promise, 介绍其如何使用,多么强大?
No, No, No, 这一上来就直奔菊花的节奏显然是会带来痛苦的。
好比超人哥哥,如果对民众大肆宣扬其多么强大——揉不扁、锤不烂,上天入地是小菜。不怕枪、不怕弹,眼睛镭射狂点赞!
民众只会害怕,排斥,认为这是一个怪物。为何?因为缺乏完整的感性认识。相比强大与否,是敌是友,是好事是坏才是让民众接受的最先考虑的,恰好,此时发生了一连串的实际,超人哥哥以行动表明了自己是站在地球这一边的。
于是,美利坚才会如此迅速认可这位超人哥哥。
我们再来看Promise, 对于部分人而言,接触过类似概念或者有类似需求,本身就有感性认识,因此,此物出现的时候,好比久旱逢甘雨,干柴遇烈火,立马high起啊~
但是,大部分的人是第一次触碰Promise的肌肤。因此,在深入介绍之前,感性认识就尤为重要,否则,会害怕,排斥,扔在一边,等着以后吃现成饭。
我们看电影、电视剧时候都会关注剧情简介;授课或演讲时候会先说个大纲。这些其实都是先塑造感性认识,说白了,就是“脑补形象”。
所以,本文不会详细、完整介绍Promise的使用、特点等。这些您可以参考本文末尾留下的相关文章地址。只会让你对Promise有个感性认知,在脑中塑造出一个物体形象,或大叔、或萝莉、或御姐、或多来A梦、或**棒等。这样,才会有兴趣、才会更快的接受相关技术点、功能、使用技巧等。
OK,首先第1点,Promise是一种形式。
注意这里的措辞,“Promise是一种形式”,也就是不要把Promise看成是某些方法、函数之类的。类似于不要把“小姐”看成某个人,而是某种职业。
Promise中文有“誓言”、“承诺”之意。从字面意思我们也似乎体会出一点“形式”的味道。但是,注意这里的转折,根据自己的理解,Promise完全不能按照“承诺”来理解,而是要根据其音译——“普罗米修斯”。普罗米修斯是希腊神话故事中的英雄,名字的意思是“先知”。Promise最初的命名是Futures, “未来”,可见Promise含义不是字面的“誓言”“承诺”之类,而是“先知”“未来”的意思。
那该如何理解“先知”,JS与先知有什么关系?
我们都知道,JS是单线程的,也就是一条线下来的,这是代码世界的一条规则。那么现实世界有与之呼应的吗?——人?No, No, 人是多线程的,人可以一边看动作片,一边撸智深。那是什么东西呢?哈,没错,时间,现实世界里,时间这条线就是单线程的,不会出现两条时间线,这种事是会出现在科幻故事里。
人当下所经历的现实世界中,很多行为结果是未知的,不是即时呈现的。例如,今天的NFL超级碗,巨星曼宁率领的野马队与本赛季黑马海鹰队的比赛。这实际上是个异步的过程,某明星压了1000万赌注野马队赢,比赛的结果会影响这位明星状态。这就类似于JS中发送一个异步的Ajax请求,不同的返回值造成不同的影响。
而Promise则扮演了一个“先知”的角色。预先将你的未来告知,规划好你继续的路。你无需等待最终结果出来,你可以继续你现在的生活。用一个简单的图表示就是下面这样:
如果你是一个先知,你是没有等待、异步这种感觉的。这就是Promise的作用,一种“先知”的形式。好比上帝,已经在他的时间维度的一瞬间规划好了你的一生(因为他有先知的能力)(他无需跟着经历你的时间),虽然你自己依然感受到了时间,以及各种变数。
对于JS代码而言,我们就是上帝。我们能够预知代码的走向,并规划好代码的人生。
回到当下,正在电脑前的我们,想想你会经历的事情,可能就会是下面这样子——沿着时间线,一种事情连着另外一件事,每件事都有多种可能的发展:
这就好比JS世界中的异步操作,例如Ajax请求,现实世界中,大部分的操作结果都不是即时显现的(类似Ajax操作),如果用JS表示我们的一生,那就会是一个超级无限长的嵌套。
实际上,无限的嵌套更符合我们当下所感受的世界的理解。既然如此,那为何我们写代码的时候不喜欢一堆嵌套呢?
很简单,我们写代码的时候,是以上帝的身份来处理代码的,我们是造物主;而不是以代码中的角色身份。目前的JS异步回调就是按照代码视角——随着时间推移,代码中的人和物会经历什么什么。那如何变成先知视角呢?很简单,使用Promise! 而这,就是Promise出现的意义:“将异步操作转换成更符合先知视角的形式展现”!
二、Promise-更符合现实世界的直觉认识
我们之于代码为先知,如果我们知晓某一个现实世界故事发展走向,其实我们也是先知。因此,很多时候,除了自己正在经历的未知的经历,我们可以使用Promise将现实世界映射。
早在11年,我写过一篇名叫“”文章,讲的就是如何站在代码的层面,脱离现实世界的思维方式,以空间换时间来更简单实现我们需要的效果。
Promise与之类似,也可以说是一种思维方式的转变,Promise似乎能更好地映射现实世界,使事情的发展更符合我们的直觉(看完本文就知道其含义了~~)。
讲一个现实世界的故事吧。
男神觉得时机成熟了,手捧99朵披着月季的玫瑰向女神求婚:
“小妞妞,嫁给我吧!我发誓,我会对你一辈子好的!”
“这个嘛,你先去问问我爸爸,我大伯以及我大姑的意思,他们全部都认可你,我再考虑考虑!对了,如果我爸没有答复,大伯他们肯定是不会同意的;如果大伯没有答复,大姑也是不会同意的。”
如果你是男神,你会怎么做?
我的第一反应(直觉)是这样的:
买些好烟好酒登门拜访岳父大人,恳请岳父大人把女儿许配给自己;1日后,得到岳父答复,如果同意,攻略大伯;如果不同意,继续攻略1次,要是还不行,失败告终;
同上攻略大伯;
买上等化妆品,然后同上攻略大姑;
拿着满满的offer拿下女神。
这是我们现实世界思维方式下的直觉反应,很简单的,也很好懂。
但是如果我们使用目前的JS实现,会是怎样?
因为得到长辈同意是需要等待的,而且一次只能攻略一个长辈,而且还能重复攻略。如果我们使用当下的JS去套用现实逻辑,可能就会这样子(无需细看):
男神.请求({
姓名: "岳父",
成功: 男神.继续请求({
姓名: "大伯",
成功: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
失败: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
失败: "求婚失败"
失败: 男神.继续请求({
姓名: "大伯",
成功: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
失败: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
失败: "求婚失败"
失败: "求婚失败"
失败: 男神.请求({
姓名: "岳父",
成功: 男神.继续请求({
姓名: "大伯",
成功: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
失败: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
失败: "求婚失败"
失败: 男神.继续请求({
姓名: "大伯",
成功: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
失败: 男神.继续请求({
姓名: "大姑",
成功: 男神.最终请求({
姓名: "女神",
成功: "求婚成功",
失败: "求婚失败"
失败: "求婚失败"
失败: "求婚失败"
失败: "求婚失败"
立马就晕了!
为何按照现实思维,JS呈现的会这么复杂呢?
代码需要预先设定好未来要发生的事情(先知视角);但是现实世界并不会如此(经历者视角);
代码中,空间是稀缺资源;而现实世界中,时间才是。
因此,在传统的JS中,类似这种多嵌套,多异步,多发展的,我们需要牺牲(对于程序来讲)微不足道的时间换取代码的空间和易维护性,于是,我可能就会这么实现(也无需细看):
var NanShen = {
"身高": 180,
"体重": 80,
"年薪": "200K",
request: function(obj) {
// 攻略长辈成功与否随机决定
// 成功概率为80%
if (Math.random() > 0.2) {
obj.success();
obj.error();
var Request = function(names, success) {
var index = 0, first = 0;
var request = function() {
if (names[index]) {
NanShen.request({
name: names[index],
success: function() {
first = 0;
console.log("成功拿下" + names[index]);
request();
error: function() {
if (first == 1) {
console.log("依旧没能拿下" + names[index] + ",求婚失败");
console.log("没能拿下" + names[index] + ",再试一次");
first = 1;
request();
success();
request();
Request(["岳父", "大伯", "大姑"], function() {
NanShen.request({
name: "女神",
success: function() {
console.log("女神同意,求婚成功!");
error: function() {
console.log("女神不同意,求婚失败!");
上面代码通过异步回调,有效重复利用了JS代码,实现了男神的求婚历程。
您可以狠狠地点击这里:
男神的每次攻略成功率是80%, 因此,其攻略结果可能是这样:
或者这样:
或者这样:
等。自己进入demo死命刷新测试自己人品吧~
————–低调的分隔线————-
不能因为本文主角是Promise就厚此薄彼,上面的JS实现是很赞的,以一种带有Promise的味道将多条件多异步的复杂世界用JS呈现出来,也是一种很巧妙的形式转化,套个噱头应该可以叫做“xxx模式”,呵呵~
然后,上面方法,依次执行的触发依然在回调中,其实并不符合我们现实的思考。我们可能希望得到的代码具有如下与现实世界统一的思维:“搞定岳父→搞定大伯→搞定大姑→搞定女神”,但是,上面的实现却看不出这样的思维。而Promise这种形式可以让代码呈现更符合真实世界的直觉。在这个故事里,女神其实已经把故事的走向全部告诉你了,这种情况下,我们其实已经知晓了未来,我们已经是先知,显然,使用Promise是很可行的。
那使用Promise该是什么模样呢?可参考下面的代码以及demo.
// 男神的各项参数
var NanShen = {
"身高": 180,
"体重": 80,
"年薪": "200K",
request: function(obj) {
// 成功与否随机决定
// 执行成功的概率为80%
if (Math.random() > 0.2) {
obj.success();
obj.error();
var Request = function(name) {
return new Promise(function(resolve, reject) {
var failed = 0, request = function() {
NanShen.request({
name: name,
success: function() {
console.log(name + "攻略成功!");
failed = 0;
resolve();
error: function() {
if (failed == 0) {
console.log("第一次攻略" + name + "失败,重试一次!");
failed = 1;
// 重新攻略一次
request();
console.log("依然没有拿下" + name + ",求婚失败!");
request();
Request("岳父")
// 搞定岳父,然后...
.then(function() { return Request("大伯"); })
// 搞定大伯,然后...
.then(function() { return Request("大姑"); })
// 搞定大姑,然后...
.then(function() {
// 长辈们全部KO后,攻略女神
NanShen.request({
name: "女神",
success: function() {
console.log("女神同意,求婚成功!");
error: function() {
console.log("女神不同意,求婚失败!");
代码没必要细看。等以后Promise规范成熟之后再细细研究。
哈,忘记demo了,您可以狠狠地点击这里:
一样的风格,一样的味道,一样的随机攻略结果,例如像下面这样死在大伯手上:
虽然代码量和传统JS实现不分伯仲,但是,注意这里,下面截图所示这圈代码:
截图上的文字是:
对于先知的我们,故事的安排在脑中是即时出现的,而非实际上的异步发生。因此,作为创世的编程者而言,这种与瞬间思考所同步的代码更符合现实世界下的思考方式。因此,更易读更易于理解。
无论是代码世界中的编程还是现实世界的讲故事,我们都是一个先知的角色(除非你能让机器自我学习,无法预知其走向),都是Promise.
现实世界中,我们要讲一个故事,都是一瞬间在脑中知晓(没有异步,等待时间经历的过程),例如教授死了,炸鸡啤酒女会哭得死去活来。在写代码逻辑的时候,脑中的反应也是如此,一瞬间知晓逻辑变化,if(Jiaoshou == "dead") { crying~ }, 是先知。因此,我们更乐意看到符合我们瞬时思维的代码呈现,而不是符合实际发展的代码呈现。
先知思维的代码呈现就是Promise形式;当局者思维的代码呈现就是异步回调形式。
如果套用求婚的故事,则:
先知思维(第三人称视角)——搞定岳父→搞定大伯→搞定大姑→搞定女神
当局者思维(第一人称视角)——去搞定岳父→…等待期…结果来了…→去搞定大伯→…等待期…结果来了…→去搞定大姑→…等待期…结果来了…→去搞定女神→…等待期…结果来了…
前者是先知是上帝,在规划;后者是凡人,在经历。
Codeing以及讲故事都是规划,因此,Promise这种先知形式会让代码更符合我们的认知。说白了就是更好懂,更好维护,可以怎么想就怎么写,而无需写着写着发现丫的需要嵌套需要再套一个函数做回调。
三、结语以及Promise其他相关
ES6中除了Promise, 还有其他一些高级的东西,例如Generator, let, for-of. 不过先暂时放在一边,回头再掌握。
还是那句话,Promise只是让我们当下的JS换了一种形式实现,更符合编程时候的思考角度与方式。因此,通过特定的转换,我们也可以让不支持Promise的低版本浏览器支持之。您可以试试在页面引入如下JS:
&script src="/es6-promises/promise-0.1.1.min.js">&/script>
GitHub点击。
这也是Promise有众多关注的原因之一。
人总是有差异的。看到一件事物总是会有不同的认知的。例如,看到一幅盛开的菊花的图片,有人会认为这是菊花,还有人会这是“菊花”。对于Promise也是如此。但是,无论你怎么思考,符合你自己的思维方式,适合你自己内心世界的都是正确的认知。So, 又会被人批评啰嗦的本文所阐述的一些感性认知,如果您有不同的看法,有不同的形象认知,都是OK的,是很赞的,也是希望能有不同的感性认知的!
感性这东西,就像发动机里的润滑油,寒冬里的温暖阳光,会让事情变得妙不可言。
欢迎交流,欢迎探讨。
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:
(本篇完)
相关文章 (0.970) (0.030) (0.030) (0.030) (0.030) (0.030) (0.030) (0.030) (0.030) (0.030) (RANDOM - 0.030)
标签: , ,
赞助商推荐():
想学到点真东西?
如果你有1~3年前端开发经验,不妨
热门总排行

我要回帖

更多关于 java yield的作用 的文章

 

随机推荐