es6的相关学习
1.关于setTimeout()
函数的写法
在es6之前与正常函数一样有函数声明式和函数表达式,如下:其中值得注意的是,setTimeout()
函数内部的作用域都是指向全局的,也就是说this指向window对象。
//函数表达式
var t=setTimeout(function(){},3000)
//函数声明
setTimeout(function(){},3000)
而在es6里,使用箭头函数,作用域则是指向为定义这个箭头函数所在的函数,同样有两种写法:
setTimeout(()=>{
resolve();
},3000)
2.继续学习async
函数
async函数返回一个 Promise 对象。
(1)async函数内部return语句返回的值,会成为then方法回调函数的参数。
async function f() {
return 'hello world';
}
f().then(v => console.log(v))
// "hello world"
上面代码中,函数f内部return命令返回的值,会被then方法回调函数接收到。
(2)任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。
async function f() {
await Promise.reject('出错了');
await Promise.resolve('hello world'); // 不会执行
}
上面代码中,第二个await语句是不会执行的,因为第一个await语句状态变成了reject。
(3)有时,我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch
结构里面,这样不管这个异步操作是否成功,第二个await都会执行。
(疑问,那这两个操作基本就没关系了。何必要放在一个async函数里呢?
解答:虽然是否成功第二个函数都会执行,但是如果要保证第一个函数必须在第二个函数之前执行,这样写是没问题的)
async function f() {
try {
await Promise.reject('出错了');
} catch(e) {
}
return await Promise.resolve('hello world');
}
f()
.then(v => console.log(v))
// hello world
(4)如果await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject。
async function f() {
await new Promise(function (resolve, reject) {
throw new Error('出错了');
});
}
f()
.then(v => console.log(v))
.catch(e => console.log(e))
// Error:出错了
如果有多个await命令,可以统一放在try...catch
结构中。
使用try...catch
结构优化写法为:
async function main() {
try {
const val1 = await firstStep();
const val2 = await secondStep(val1);
const val3 = await thirdStep(val1, val2);
console.log('Final: ', val3);
}
catch (err) {
console.error(err);
}
}
(5)await命令只能用在async函数之中,如果用在普通函数,就会报错。
(6)js里的作用域链相关
简单的来说,就是函数从内到外寻找作用域。里面可以访问外面的,而外面不能访问里面的。
值得注意的是var变量声明存在变量提升,而es6里的let则不存在。