本文为拉勾网大前端高薪训练营第一期笔记
JavaScript执行时是单线程的,但是浏览器不是单线程的,比如内部API webapi会有别的线程执行,比如setTimeout
- Promise对象的then方法会返回一个全新的Promise对象
- 后面的then方法就是在为上一个then返回的Promise注册回调
- 前面then方法中回调函数的返回值会作为后面then方法回调的参数
- 如果回调中返回的是Promise,那后面then方法的回调会等待它的结束
then里其实传两个回调参数,第一个onFulfilled,第二个onRejected,只是一般省略第二个
.then(function onFulfilled(value){},
function onRejected(error{})
常见的还是.catch(()⇒{})
全局捕获uncatched error
window.addEventListener('unhandledrejection', event => {
const { reason, promise } = event
console.log(reason, promise)
// reason => Promise 失败原因,一般是一个错误对象
// promise => 出现异常的 Promise 对象
event.preventDefault()
}, false)
// Node.js 中使用以下方式
// process.on('unhandledRejection', (reason, promise) => {
// console.log(reason, promise)
// // reason => Promise 失败原因,一般是一个错误对象
// // promise => 出现异常的 Promise 对象
// })
大部分异步调用都是作为宏任务执行
微任务:
- Promise
- MutationObserver
- node里的process.nextTick
例子
generator的next的第一次传入参数会被忽略,next的传参会替换上一个yield,第一次传参前没有yield
https://medium.com/dailyjs/a-simple-guide-to-understanding-javascript-es6-generators-d1c350551950
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
// function *generatorFunction(i) {
// console.log(0, i) //0 10
// const j = 5 * (yield(i * 10))
// console.log(2, j) //2 50
// const k = yield(2 * j / 4)
// console.log(4, k) //4 5
// return (i + j + k)
// }
//
// var generator = generatorFunction(10)
//
// console.log(1, generator.next(20)) //1 { value: 100, done: false }
// console.log(3, generator.next(10)) //3 { value: 25, done: false }
// console.log(5, generator.next(5)) //5 { value: 65, done: true }
// 0 10
// 1 { value: 100, done: false }
// 2 50
// 3 { value: 25, done: false }
// 4 5
// 5 { value: 65, done: true }
// function *generatorFunction(){
// yield
// foo(yield "I am usless")
// }
//
// function foo(x){
// console.log('just printing argument passed ' + x)
// }
//
// var generator = generatorFunction()
//
// console.log(generator.next())
// console.log(generator.next())
// console.log(generator.next())
// { value: undefined, done: false }
// { value: 'I am usless', done: false }
// just printing argument passed undefined
// { value: undefined, done: true }
// function* genFuncChild() {
// yield 1
// yield 2
// return 'foo'
// yield 3
// }
//
// function* genFuncMain(){
// const result = yield* genFuncChild()
// console.log(2, result)
// yield 'the end'
// }
//
// var generator = genFuncMain()
//
// console.log(0, generator.next())
// console.log(1, generator.next())
// console.log(3, generator.next())
// console.log(4, generator.next())
// { value: 1, done: false }
// { value: 2, done: false }
// foo
// { value: 'the end', done: false }
// { value: undefined, done: true }
// function* genFuncChild() {
// yield 1
// yield 2
// return 'foo'
// yield 3
// }
//
// function* genFuncMain(){
// const result = yield* genFuncChild()
// console.log(2, result)
// yield 'the end'
// }
//
// var generator = genFuncMain()
//
// for(let i of generator){
// console.log(i)
// }
// 1
// 2
// 2 'foo'
// the end
// function* g3() {
// yield* [1, 2];
// yield* '34';
// yield* Array.from(arguments);
// }
//
// const iterator = g3(5, 6);
//
// console.log(iterator.next()); // {value: 1, done: false}
// console.log(iterator.next()); // {value: 2, done: false}
// console.log(iterator.next()); // {value: "3", done: false}
// console.log(iterator.next()); // {value: "4", done: false}
// console.log(iterator.next()); // {value: 5, done: false}
// console.log(iterator.next()); // {value: 6, done: false}
// console.log(iterator.next()); // {value: undefined, done: true}
// function* g4() {
// yield* [1, 2, 3];
// return 'foo';
// }
//
// function* g5() {
// const g4ReturnValue = yield* g4();
// console.log(g4ReturnValue) // 'foo'
// return g4ReturnValue;
// }
//
// const iterator = g5();
//
// console.log(iterator.next()); // {value: 1, done: false}
// console.log(iterator.next()); // {value: 2, done: false}
// console.log(iterator.next()); // {value: 3, done: false} done is false because g5 generator isn't finished, only g4
// console.log(iterator.next()); // {value: 'foo', done: true}
// { value: 1, done: false }
// { value: 2, done: false }
// { value: 3, done: false }
// foo
// { value: 'foo', done: true }
function* logGenerator() {
console.log(0);
console.log(1, yield);
console.log(2, yield);
console.log(3, yield);
}
var gen = logGenerator();
// the first call of next executes from the start of the function
// until the first yield statement
gen.next(); // 0
gen.next('pretzel'); // 1 pretzel
gen.next('california'); // 2 california
gen.next('mayonnaise'); // 3 mayonnaise
function* yieldAndReturn() {
yield "Y";
return "R";
yield "unreachable";
}
var gen = yieldAndReturn()
console.log(gen.next()); // { value: "Y", done: false }
console.log(gen.next()); // { value: "R", done: true }
console.log(gen.next()); // { value: undefined, done: true }
const someObj = {
*generator () {
yield 'a';
yield 'b';
}
}
const gen = someObj.generator()
console.log(gen.next()); // { value: 'a', done: false }
console.log(gen.next()); // { value: 'b', done: false }
console.log(gen.next()); // { value: undefined, done: true }
class Foo {
*[Symbol.iterator] () {
yield 1;
yield 2;
}
}
const SomeObj = {
*[Symbol.iterator] () {
yield 'a';
yield 'b';
}
}
console.log(Array.from(new Foo)); // [ 1, 2 ]
console.log(Array.from(SomeObj)); // [ 'a', 'b' ]
本文为拉勾网大前端高薪训练营第一期笔记