前言
Promise async generator是ES6之后才被提出来的,他们都能够用来解决以前JS异步调用产生的一系列问题,例如大名鼎鼎的回调地狱!!!
什么是回调地狱"htmlcode">
一次回调当然简单,如果是在这次请求完成后需要立即发起下一次请求呢?例如需要请求request10次,必须在上次请求完成后才能进行下一次请求,来看看 回调地狱 是怎么样的 这才第5次回调,但是代码的可读性已经极差了! 让我们先看看 Promise async generator怎么解决这个问题,后面再说其使用方式 首先 Promise 篇 虽然还是很长,但是至少嵌套很少了,可读性也比之前更高 再来看看 async 切记,async必须和Promise配合使用 代码是不是更加简短了?而且看起来和同步一样,事实上,这就是使用同步的方式写异步代码,这代码也是同步执行的 最后看看 generator 以上是异步编程的ES6解决方案,接下来让我们把这3种方式都详细了解下 一.Promise 关于Promise的一些原型,函数,请移步 官方链接 Promise的中文名,也就是承诺,保证, 大家可以将Promise理解为JS的一个承诺,也就是对异步操作的一个承诺,咱先不管异步操作是否能够执行成功,使用Promise的所有异步操作,JS已经承诺处理了,咱就通过Promise的状态来知晓异步操作的执行结果。 一个 Promise有以下几种状态: pending 状态的 Promise 对象可能会变为fulfilled 状态并传递一个值给相应的状态处理方法,也可能变为失败状态(rejected)并传递失败信息。当其中任一种情况出现时,Promise 对象的 then 方法绑定的处理方法(handlers )就会被调用 上文提到Promise的原型中的函数then,then可以接收2个参数(resolve [,reject]) 第一个参数resolve 是对成功的一个处理,类型为Function。你可以在其中做 一些异步成功后的操作 第二个参数reject是对失败的一个处理,类型为Function。你可以在其中做 一些异步失败后的操作 一般情况下then我们只会传一个参数,也就是默认的成功处理,失败处理会使用 catch函数 catch函数只有一个参数,也就是代表失败的reject 来看看then catch的使用案例 使用 Promise 能够使你的异步操作变得更加优雅,可读性也比较高,同时,Promise在ES6的各大插件中也使用的相当广泛,所以掌握 Promise是非常有必要的 二.async / await 想详细了解更多,请移步官方文档 async关键字用来定义一个function,用来标识此函数是一个异步函数 切记 切记 切记, await 关键字仅仅在 async function中有效。如果在 async function函数体外使用 await ,你只会得到一个语法错误SyntaxError async关键字放在函数的声明之前,例如: 无论是普通的函数,Lambda表达式,或是ES6的class,该关键字都是放置在函数的声明之前 在调用声明了async的函数时,会返回一个Promise对象 而await关键字则是放置在异步操作的调用之前,await会使得async函数在执行到异步操作时暂停代码执行,直到异步操作返回的Promise状态更改为 fulfilled 或 rejected,此时代码会继续执行,并自动解析Promise返回的值,无论是成功还是失败,都会解析到await关键字前面定义接收的参数,请看例子: 上面的实例调用show函数,会立即打印出 第一次,延时1000毫秒后,会打印出 第二次 原理嘛,就是模仿Java的线程休眠函数Sleep 在打印了 第一次 后,会调用T的Sleep函数,Sleep函数返回了一个Promise,在定时器执行完毕后调用Promise的resolve函数,会将Promise 的状态更改为 fulfilled,此时await检测到Promise的状态更改,继续执行代码,输出 第二次 三 . generator generator(生成器)是ES6标准引入的新的数据类型,使用方式是在函数名前加上*,generator和普通的函数差不多,但是可以返回多次。 嗯,所有的函数都有默认的返回值,如果没有明确定义,那就会返回undefined,generator也不例外! generator使用yield关键字来中途返回值,请看案例 第一次输出的是第一次yield的值,此时num为调用a函数时传入的值 1,yield返回了num+1,所以第一行打印的对象 value值是 2 第二次打印的是sum值,也就是第一个yield关键字前面接收的值,此值是下面result.next(2)传入的 ,next函数传入的参数,会赋值到相应的yield关键字左边接收的那个变量,在上方案例,也就是sum变量 第三次输出的是a函数中第二个yield返回的值,此时sum为第一次next(2)传入的2,所以此次返回的值是2+2,所以值也就是 4 第四次输出的是最后一个next(),但是上方generator并没有相应的yield返回,所以此时的value为undefined yield返回的值是一个对象,其中有done和value两个属性, generator是支持迭代器操作的,例: 事实证明generator是实现了迭代器的接口的! 嗯,关于generator的实际应用场景,我是没有遇见的,不过听说 async/await是generator的语法糖?? 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。
//我们需要在请求完成后输出请求完成,请看回调法
function show(params) {
request('这是请求参数', () => {
console.log('请求完成')
})
}
/**
* 模拟发起一个http请求
* @param {object} data 请求的参数
* @param {function} callBack 回调函数
*/
function request(data, callBack) {
//下面的定时器模拟请求时间
setTimeout(data => {
callBack(data);
}, 3000);
}
show()
//我们需要在请求完成后输出请求完成,请看回调法
function show(params) {
request('这是请求参数', () => {
console.log('请求完成1次')
request('这是请求参数', () => {
console.log('请求完成2次')
request('这是请求参数', () => {
console.log('请求完成3次')
request('这是请求参数', () => {
console.log('请求完成4次')
request('这是请求参数', () => {
console.log('请求完成5次')
//这才第五次.....
})
})
})
})
})
}
/**
* 模拟发起一个http请求
* @param {object} data 请求的参数
* @param {function} callBack 回调函数
*/
function request(data, callBack) {
//下面的定时器模拟请求时间
setTimeout(data => {
callBack(data);
},1000);
}
show()
//我们需要在请求完成后输出请求完成,请看回调法
function show(params) {
request('这是请求参数').then(
resolve => {
console.log('请求完成1次');
return request('这是请求参数')
}
).then(
resolve => {
console.log('请求完成2次');
return request('这是请求参数')
}
).then(
resolve => {
console.log('请求完成3次');
return request('这是请求参数')
}
).then(
resolve => {
console.log('请求完成4次');
return request('这是请求参数')
}
).then(
resolve => {
console.log('请求完成5次');
return request('这是请求参数')
}
)
}
/**
* 模拟发起一个http请求
* @param {object} data 请求的参数
* @param {function} callBack 回调函数
*/
function request(data) {
return new Promise(
resolve => {
//下面的定时器模拟请求时间
setTimeout(data => {
resolve(data)
}, 1000);
}
)
}
show()
//我们需要在请求完成后输出请求完成,请看回调法
async function show(params) {
let result = await request('这是请求参数')
console.log('请求完成1次');
result = await request('这是请求参数')
console.log('请求完成2次');
result = await request('这是请求参数')
console.log('请求完成3次');
result = await request('这是请求参数')
console.log('请求完成4次');
result = await request('这是请求参数')
console.log('请求完成5次');
}
/**
* 模拟发起一个http请求
* @param {object} data 请求的参数
* @param {function} callBack 回调函数
*/
function request(data) {
return new Promise(
resolve => {
//下面的定时器模拟请求时间
setTimeout(data => {
resolve(data)
}, 1000);
}
)
}
show()
//我们需要在请求完成后输出请求完成,请看回调法
function* show() {
let a1 = yield request('请求参数', () => {
console.log('这是第1次调用');
});
let a2 = yield request('请求参数', () => {
console.log('这是第2次调用');
});
let a3 = yield request('请求参数', () => {
console.log('这是第3次调用');
});
let a4 = yield request('请求参数', () => {
console.log('这是第4次调用');
});
let a5 = yield request('请求参数', () => {
console.log('这是第5次调用');
});
}
/**
* 模拟发起一个http请求
* @param {object} data 请求的参数
* @param {function} callBack 回调函数
*/
function request(data, callBack) {
//下面的定时器模拟请求时间
setTimeout(() => {
callBack(data)
}, 1000);
}
let a = show()
a.next();
a.next();
a.next();
a.next();
a.next();
function show(params) {
//正常的请求成功操作
request('这是请求参数').then(
resolve => {
console.log(resolve);
}
)
//在then里面同时做成功和失败的操作
request('这是请求参数').then(
resolve => {
//这儿是成功
console.log(resolve);
},
reject => {
//这儿是失败
console.log(reject);
}
)
//正常的请求失败操作
request('这是请求参数').catch(
reject => {
console.log(reject);
}
)
}
/**
* 模拟发起一个http请求
* @param {object} data 请求的参数
* @param {function} callBack 回调函数
*/
function request(data) {
return new Promise(
(resolve, reject) => {
//下面的定时器模拟请求时间
setTimeout(data => {
// resolve('请求成功')
reject('请求失败')
}, 1000);
}
)
}
show()
async function test() {
}
async () => {
}
async data => {
}
class Test {
async show() {
}
}
class Test {
/**
* 线程休眠
* @param {number} timer 休眠毫秒数
*/
Sleep(timer) {
return new Promise(
resolve => {
setTimeout(() => {
resolve(timer)
}, timer);
}
)
}
}
let T = new Test();
async function show() {
console.log('第一次');
await T.Sleep(1000)
console.log('第二次');
}
show()
function* a(num) {
let sum = yield num + 1
console.log(sum);//2 此处是next(r.value)传入的值
let sum2 = yield sum + 2
}
let result = a(1);
let r = result.next()
console.log(r);//此处返回第一次yield的值 2
console.log(result.next(2));//此处返回第二次yield的值 4
console.log(result.next());//此处并没有第三次yield
function* a(num) {
let sum = yield num + 1
console.log(sum);//2 此处是next(r.value)传入的值
let sum2 = yield sum + 2
}
let result = a(1);
for (const key of result) {
console.log(key);
}
es6异步,es6异步加载
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 《庄心妍 实力唱将 发烧音乐精选集》[WAV+CUE][380MB]
- [音展纪念碟]2006年《TAA台湾第十六届国际HI-ENDHI-FI音响展》2cd[WAV]
- 中国音乐地图之听见西藏山歌牧歌酒歌2020[WAV分轨]
- 王宏伟2017-永远的红飘带[太平洋影音][WAV+CUE]
- 费翔.1997-NOW现在【第一中国】【WAV+CUE】
- 新格合唱团.1981-我唱你和2辑(滚石新格民歌系列)【新格】【WAV+CUE】
- 陈柏宇.2011-QUINQUENNIUM【SONY】【WAV+CUE】
- 雨果唱片-《金唛系列-蔷薇依韵琼瑶》WAV
- 陈百强《凝望(2012华纳LPCD45限量版)[DMI]》[WAV整轨]
- 模拟之声慢刻CD《徐小凤45周年》[德国母带][低速原抓WAV+CUE]
- 《庄心妍 实力唱将 发烧音乐精选集》[WAV+CUE][380MB]
- 《王菲 单曲合集》[FlAC/分轨][520MB]
- 《费玉清 原味再现 水长流》[WAV+CUE][430MB]
- 群星.1992-畅销榜老歌金曲10CD【风格】【WAV+CUE】
- 孙悦.2024-时光音乐会【金蜂】【WAV+CUE】