Event Loop
Promise
概念
new Promise((resolve, reject) => {})
里面的函数是同步(立刻)执行,then/catch/finally
里面的函数是异步(进入微任务队列)执行
微任务队列:Promise.then/catch/finally
、MutationObserver
、process.nextTick
、Object.observe
宏任务队列:setTimeout
、setInterval
、setImmediate
、requestAnimationFrame
、I/O
、UI rendering
微任务队列优先级高于宏任务队列。在每一次事件循环中,只要调用栈为空,就会先执行微任务队列中的任务,直到微任务队列为空,再执行宏任务队列中的任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| console.log(1);
setTimeout(() => { console.log(2); }, 0);
const promise = new Promise((resolve, reject) => { console.log(3); resolve(4); });
promise.then((res) => { console.log(res); });
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| const p1 = () => new Promise((resolve, reject) => { console.log(1);
let p2 = new Promise((resolve, reject) => { console.log(2);
const timeOut1 = setTimeout(() => { console.log(3); resolve(4); }, 0);
resolve(5); });
resolve(6);
p2.then((arg) => { console.log(arg); }); });
const timeOut2 = setTimeout(() => { console.log(8); const p3 = new Promise((reject) => { reject(9); }).then((res) => { console.log(res); }); }, 0);
p1().then((arg) => { console.log(arg); });
console.log(10);
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| const p1 = new Promise((resolve) => { setTimeout(() => { resolve(1); }, 3000); });
const p2 = new Promise((resolve) => { setTimeout(() => { resolve(2); }, 2000); });
const p3 = new Promise((resolve) => { setTimeout(() => { resolve(3); }, 1000); });
function execute() { p1.then((data) => console.log(data)); p2.then((data) => console.log(data)); p3.then((data) => console.log(data)); }
execute();
|
Async/Await
概念
async
函数是 Generator
和 Promise
的语法糖
async
函数返回一个 Promise
对象,await
表达式会暂停 async
函数的执行,等待 Promise
的解决,然后恢复 async
函数的执行并返回解决值
可以转换成 Promise
的写法,见示例。实际并不是这么执行的!!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| async function async1() { console.log('1'); await async2(); console.log('2'); }
async function async2() { console.log('3'); }
async1();
console.log('4');
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function async1() { console.log('1'); return async2().then(() => { console.log('2'); }); }
function async2() { console.log('3'); return Promise.resolve(''); }
async1();
console.log('4');
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| const p1 = new Promise((resolve) => { setTimeout(() => { resolve(1); }, 3000); });
const p2 = new Promise((resolve) => { setTimeout(() => { resolve(2); }, 2000); });
const p3 = new Promise((resolve) => { setTimeout(() => { resolve(3); }, 1000); });
async function execute() { await p1.then((data) => console.log(data)); await p2.then((data) => console.log(data)); await p3.then((data) => console.log(data)); }
execute();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| const p1 = new Promise((resolve) => { setTimeout(() => { resolve(1); }, 3000); });
const p2 = new Promise((resolve) => { setTimeout(() => { resolve(2); }, 2000); });
const p3 = new Promise((resolve) => { setTimeout(() => { resolve(3); }, 1000); });
function execute() { return p1 .then((data) => { console.log(data); return p2; }) .then((data) => { console.log(data); return p3; }) .then((data) => { console.log(data); }); }
execute();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| async function async1() { console.log('1'); return '2'; }
async function async2() { console.log('3'); return Promise.resolve('4'); }
async function test() { console.log('5'); const v1 = await async1(); console.log(v1); const v2 = await async2(); console.log(v2); }
test();
var promise = new Promise((resolve) => { console.log('6'); resolve('7'); });
promise.then((val) => console.log(val));
console.log('8');
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| function async1() { console.log('1'); return Promise.resolve('2'); }
function async2() { console.log('3'); return Promise.resolve('4'); }
function test() { console.log('5'); return async1() .then((v1) => { console.log(v1); return async2(); }) .then((v2) => { console.log(v2); }); }
test();
var promise = new Promise((resolve) => { console.log('6'); resolve('7'); });
promise.then((val) => console.log(val));
console.log('8');
|
Promise 的 API 方法
Promise.all
Promise.all
方法接受一个 Promise
可迭代对象,并返回一个新的 Promise
只有当所有的 Promise
都 resolve
时,返回的 Promise
才会 resolve
,并以一个包含所有 resolve
值的数组作为结果
如果任何一个 Promise
reject
,返回的 Promise
将 reject
,并带有该 Promise
的 reject
原因
1 2 3 4 5
| const p1 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'one')); const p2 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'two')); const p3 = new Promise((resolve, reject) => setTimeout(resolve, 300, 'three'));
Promise.all([p1, p2, p3]).then(console.log);
|
Promise.race
1 2 3 4
| const p1 = new Promise((resolve, reject) => setTimeout(resolve, 500, 'one')); const p2 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'two'));
Promise.race([p1, p2]).then(console.log);
|
Promise.any
Promise.any
方法接受一个 Promise
可迭代对象,并返回一个新的 Promise
只要迭代中的任何一个 Promise
resolve
,返回的 Promise
就会 resolve
,并以该 Promise
的 resolve
值作为结果
如果所有的 Promise
都 reject
,返回的 Promise
将 reject
,并带有一个聚合的 reject
原因(一个 AggregateError
对象)
1 2 3 4 5
| const p1 = new Promise((resolve, reject) => setTimeout(reject, 100, 'one')); const p2 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'two')); const p3 = new Promise((resolve, reject) => setTimeout(resolve, 300, 'three'));
Promise.any([p1, p2, p3]).then(console.log);
|