异步操作
异步操作会在将来的某个时间点触发一个函数调用
传统回调
fetch('https://api.github.com/users').then(res => res.json()).then(json => {
console.log(json)
fetch('https://api.github.com/users/Geronimomiao').then(res => res.json()).then(json2 => {
console.log(json2)
})
})
async await
(async() => {
const res = await fetch('https://api.github.com/users');
const json = await res.json();
console.log(json);
const res2 = await fetch('https://api.github.com/users/Geronimomiao');
const json2 = await res2.json();
console.log(json2);
})()
promise
-
pending: 初始状态.
-
fulfilled: 成功的操作.
-
rejected: 失败的操作.
-
无法取消Promise,一旦新建它就会立即执行,无法中途取消
-
一旦状态改变,就不会再变,任何时候都可以得到这个结果
-
对象的状态不受外界影响
面试题
setTimeout(function(){console.log(4)},0);
new Promise(function(resolve){ console.log(1); for( var i=0 ; i<10000 ; i++ ){ i==9999 && resolve() } console.log(2) }).then(function(){ console.log(5) }).then(function(){ console.log(6) }).then(function(){ console.log(7) });
console.log(3);
1,2,3,5,6,7,4
原因:有一个事件循环,但是任务队列可以有多个。整个script代码,放在了macrotask queue中,setTimeout也放入macrotask queue。但是,promise.then放到了另一个任务队列microtask queue中。这两个任务队列执行顺序如下,取1个macrotask queue中的task,执行之。然后把所有microtask queue顺序执行完,再取macrotask queue中的下一个任务。代码开始执行时,所有这些代码在macrotask
queue中,取出来执行之。后面遇到了setTimeout,又加入到macrotask queue中,然后,遇到了promise.then,放入到了另一个队列microtask queue。等整个execution context
stack执行完后,下一步该取的是microtask queue中的任务了。因此promise.then的回调比setTimeout先执行。
优先级关系
process.nextTick > promise.then > setTimeout > setImmediate
V8实现中,两个队列各包含不同的任务
macrotasks: script(整体代码),setTimeout, setInterval, setImmediate, I/O, UI rendering
microtasks: process.nextTick, Promises, Object.observe, MutationObserver
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('开始');
resolve('success');
}, 5000);
});
const start = Date.now();
promise.then((res) => {
console.log(res, Date.now() - start);
});
promise.then((res) => {
console.log(res, Date.now() - start);
});
promise 的.then或者.catch可以被调用多次,但这里 Promise 构造函数只执行一次。或者说 promise 内部状态一经改变,并且有了一个值,那么后续每次调用.then 或者.catch都会直接拿到该值
let p2 = new Promise((resolve, reject) => {
console.log(111);
resolve(6);
})
p2()