0
点赞
收藏
分享

微信扫一扫

es6详解promise,async,await


新数据类型symbol

特点

  • 不能使用new创建,只能let syml = Symbol(‘aaa’)
  • Symbol()返回是唯一的值。
  • 单独的数据类型
  • 在symbol作为key的时候,用 for in 不能循环出来

例子

let syml = Symbol('aaa')

// console.log(syml)

let json = {
'a': 'apple',
'b': 'banana',
[syml]: 'other'
}

// console.log(json[syml])

for(let key in json){
console.log(key)
}

promise

特点

  • Promise 是异步编程的一种解决方案.
  • 简单说就是一个​​容器​​​,里面保存着某个未来才会结束的事件(通常是一个​​异步操作​​)的结果。
  • Promise 是一个​​对象​​​,从它可以​​获取异步操作的消息​​。
  • 对象的状态不受外界影响。1. 此操作异步操作有三种状态:​​pending​​​(进行中)、​​fulfilled​​​(已成功)和​​rejected​​(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
  • 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从​​pending​​​变为​​fulfilled​​​和从​​pending​​​变为​​rejected​​。
  • resolve reject 只执行一个且为函数
  • 执行顺序 先执行promise中的函数 – 当前队列中同步代码 – then 中代码
  • promise代码是错误,也是执行then中的reject方法, 并会讲错误信息传给他

async,await

特点

  • async函数​​返回​​​一个 ​​Promise 对象​​(让一个方法变为异步方法)。
  • async函数内部​​return语句返回的值​​​,会成为​​then​​​方法​​回调函数的参数​​。
  • await new promise() ; 直接让promise 去执行 并返回执行的参数;
  • 等await 后面的异步代码完成后,再去执行后面的代码
  • await 是语法糖 不用通过then就可以拿到resolve或reject的参数
  • ​async​​​ 是让方法变异步, ​​await​​​是等待异步方法执行完成,可以获取异步方法里面的数据,但是必须在异步方法中使用, 还有就是可以阻塞功能,可以把异步转化为同步
    *await 需要在 async方法中使用
    例子1:

async function gen(){

//return 出的内容 就是成功回调的参数

//若出现错误 被catch捕获到
// throw new Error('error')
return '飞剑侠';
}


gen().then(res =>{
console.log(res)
}).catch(e=>{
console.log(e)
})

例子2:

let p = new Promise((resolve, reject)=>{
resolve('success')
})

async function gen(){
// await 后面是一个promise实例 如果不是 则会转为promise
// 直接让promise 去执行 并返回执行的参数
let params = await p
// 等await 后面的异步代码完成后,再去执行后面的代码
console.log(params) //success
//await 是语法糖 不用通过then就可以拿到resolve或reject的参数
return params;
}


gen().then(res =>{
console.log(res)
}).catch(e=>{
console.log(e)
})

generator

特点

  • 解决异步问题,深度嵌套
  • 可以进结构复制 let [a,b/…b] = gen()
  • 也可以使用扩展运算符
  • Array.from( gen())

例子1:

function * gen(){


yield '逍遥生'
yield '飞剑侠'
return `飞燕女`
}

let g1 = gen();

//调用
// console.log(g1.next()) //{ value: '逍遥生', done: false } false 代表函数还未执行完毕
// console.log(g1.next()) // { value: '飞剑侠', done: false }
// console.log(g1.next()) // { value: '飞燕女', done: true }

// for of return的东西不会遍历
// for(let val of g1) {
// console.log(val)
// }


//结构赋值
// let [a, b] = gen()
// console.log(a)
// console.log(b)


//扩展运算符
//会把yield的所有值 输出
// let [...a] = gen()
// console.log(a) //[ '逍遥生', '飞剑侠' ]


// console.log(Array.from(gen()))//[ '逍遥生', '飞剑侠' ]

例子2:

const axios = require('axios')

function * gen(username){

let name ;
name = yield username
yield axios.get(`https://api.github.com/users/${name}`) //这个name可以由外面提供
}

let g1 = gen('nianxiongdi')
let username = g1.next().value
// console.log(g1) { value: 'nianxiongdi', done: false }

g1.next(username).value.then(resolve => {
console.log(resolve.data.login)
}).catch((e)=>{
console.log(e)
})
// console.log( g1.next() )

async,await与promise使用例子

1. async/await函数

const fetch = require('node-fetch')

function getZhihuColumn(id) {

const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
fetch(url)
.then(response => response.json()) //把数据转化为json
.then(data => {
// console.log(data)

console.log("DES:" + `${data.description}`)
console.log("INTRO:" + `${data.intro}`)
})
}

getZhihuColumn('feweekly')

2. 将async函数用在promisechiain中

const fetch = require('node-fetch')

//修改为异步请求
// 异步代码同步处理,使用async await
// async 修饰过的 返回的都是promise 若不是 则转化为promise
async function getZhihuColumn(id) {

const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
const response = await fetch(url) // 相当于得到请求数据
// const data = await response.json()
// return data;

// 上面两行 直接修改成
return await response.json();
}
getZhihuColumn('feweekly')
.then(data =>{
console.log(`NAME: ${data.description}`)
console.log("INTRO:" + `${data.intro}`)
})

3. 把任意类型的函数 转成async风格

const fetch = require('node-fetch')

/*
把任意类型的函数 转成async风格
*/

//修改为异步请求
// 修改为箭头函数
const getZhihuColumn = async (id) => {

const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
const response = await fetch(url) // 相当于得到请求数据
// const data = await response.json()
// return data;

// 上面两行 直接修改成
return await response.json();
}

// 在async 在顶级作用域下是非法的, 所以需要使用匿名函数, 也需要声明为async
(async () => {
const data = await getZhihuColumn('feweekly');
console.log(`NAME: ${data.description}`);
console.log("INTRO:" + `${data.intro}`);
})();

const fetch = require('node-fetch')

/*
把任意类型的函数 转成async风格 在类上面的使用
*/


class APIClent {
async getColumn(id) {
const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
const response = await fetch(url) // 相当于得到请求数据
return await response.json();
}
}

// 在async 在顶级作用域下是非法的, 所以需要使用匿名函数, 也需要声明为async
(async () => {
const client = new APIClent();
const data = await client.getColumn('feweekly'); //注意别忘记加await
console.log(`NAME: ${data.description}`);
console.log("INTRO:" + `${data.intro}`);
})();

4. async 处理错误

const fetch = require('node-fetch')

/*
处理async中的错误
*/
//修改为异步请求
async function getZhihuColumn(id) {

const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
const response = await fetch(url) // 相当于得到请求数据

//从状态去判断
if(response.status !== 200){
throw new Error(response.statusText)
}

return await response.json();
}




//假如feweekly123不存在
const showColumnInfo = async (id) =>{
try {
const data = await getZhihuColumn(id)
console.log(`NAME: ${data.description}`)
console.log("INTRO:" + `${data.intro}`)
} catch (error) {
console.log(error)
}

}

showColumnInfo('feweekly123')
/*
打印的错误信息,被catch 捕获到
Error: Not Found
at getZhihuColumn (/home/nianxiongdi/Development/nodejs/es6/async/demo8.js:16:15)
at process._tickCallback (internal/process/next_tick.js:68:7)
*/

5. 正确处理多个await操作的并行串行

const fetch = require('node-fetch')

/*
正确处理多个await操作的并行串行
并行代码更快
*/
//修改为异步请求
async function getZhihuColumn(id) {

const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
const response = await fetch(url) // 相当于得到请求数据

//从状态去判断
if(response.status !== 200){
throw new Error(response.statusText)
}

return await response.json();
}


//假如feweekly123不存在
const showColumnInfo = async () =>{
try {
//串行的代码
// const feweekly = await getZhihuColumn('feweekly')
// const toolingtips = await getZhihuColumn('toolingtips')

//并行代码
const feweeklyPromise = getZhihuColumn('feweekly')
const toolingtipsPromise = getZhihuColumn('toolingtips')
const feweekly = await feweeklyPromise;
const toolingtips =await toolingtipsPromise;

console.log(`NAME: ${feweekly.description}`)
console.log("INTRO:" + `${feweekly.intro}`)

console.log(`NAME: ${toolingtips.description}`)
console.log("INTRO:" + `${toolingtips.intro}`)


} catch (error) {
console.log(error)
}

}

showColumnInfo('feweekly123')

6. 使用promise.all()让多个await操作并行

const fetch = require('node-fetch')

/*
使用promise.all()让多个await操作并行
并行代码更快
*/
//修改为异步请求
async function getZhihuColumn(id) {

const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
const response = await fetch(url) // 相当于得到请求数据

//从状态去判断
if(response.status !== 200){
throw new Error(response.statusText)
}

return await response.json();
}




//假如feweekly123不存在
const showColumnInfo = async () =>{
try {
//并行代码
//all() 本身也是返回promise实例 可以使用await
const [feweekly, toolingtips ] = await Promise.all([
getZhihuColumn('feweekly'),
getZhihuColumn('toolingtips')
])

console.log(`NAME: ${feweekly.description}`)
console.log("INTRO:" + `${feweekly.intro}`)

console.log(`NAME: ${toolingtips.description}`)
console.log("INTRO:" + `${toolingtips.intro}`)

} catch (error) {
console.log(error)
}

}

showColumnInfo('feweekly123')

7. 结合await和任意兼容.then()的代码

const bluebird = require('bluebird')
/**
* 结合await和任意兼容.then()的代码
*/

async function main(){

// const number = await 890;
/**
* 若await后面不是promise 则会转化为promise
* 上面的代码会转换为
* await Promise.resolve(890);
*/
// console.log(number)
await bluebird.delay(2000) //延迟2秒
}
main()

8. 在for循环中正确使用await

const bluebird = require('bluebird')
const fetch = require('node-fetch')

/**
* 在for循环中正确使用await
*/

async function getZhihuColumn(id) {

// await bluebird.delay(1000);

const url = `https://zhuanlan.zhihu.com/api/columns/${id}`
const response = await fetch(url) // 相当于得到请求数据

return await response.json();
}


const showColumnInfo = async () =>{
try {

console.time('showColumnInfo') //方法名

const names = ['feweekly', 'toolingtips']
/*
//方法1
for(const name of names) {
const data = await getZhihuColumn(name)

console.log(`NAME: ${data.description}`)
console.log("INTRO:" + `${data.intro}`)
}
*/

// 方法2
const promises = names.map(x => getZhihuColumn(x));
for(const promise of promises){
const data = await promise
console.log(`NAME: ${data.description}`)
console.log("INTRO:" + `${data.intro}`)
}

console.timeEnd('showColumnInfo') //方法名
} catch (error) {
console.log(error)
}
}

showColumnInfo()

修饰器

  • ​​参考​​
  • ​​https://www.npmjs.com/package/babel-plugin-transform-decorators-legacy​​
  • ​​https://babeljs.io/docs/en/babel-plugin-proposal-decorators​​ …待完善


举报

相关推荐

0 条评论