新数据类型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()