代码分析1-promise

1
js
const myPromise = new Promise((res, rej) => { console.log('A') console.log('B') }) myPromise.then(() => { console.log('C') }) console.log('D') // 答案往左滑 输出顺序:A B D
2
js
const myPromise1 = new Promise((res, rej) => { console.log('A') res('B') }) const myPromise2 = myPromise1.then(res => { console.log(res) }) console.log('C', myPromise1); console.log('D', myPromise2); // 答案往左滑 输出顺序:A C Promise {<fulfilled>: 'B'} D Promise {<pending>} B
3
js
const myPromise1 = new Promise((res, rej) => { console.log('1'); setTimeout(() => { console.log('2'); res('3'); console.log('4'); }, 0); }); myPromise1.then(res => { console.log(res); }); console.log('5'); // 答案往左滑 输出顺序:1 5 2 4 3
4
js
Promise.resolve().then(res => { console.log(1); const innerTimer = setTimeout(() => { console.log(2); }, 0); }); const timer1 = setTimeout(() => { console.log(3); Promise.resolve().then(() => { console.log(4); }); }, 0); console.log('5'); // 答案往左滑 输出顺序:5 1 3 4 2
5
js
const p1 = new Promise((res, rej) => { res('1'); rej('2'); res('3'); }); p1.then((res) => { console.log(res); }).catch((err) => { console.log(err); }); // 答案往左滑 输出顺序:1
6
js
Promise.resolve(1) .then(2) .then(Promise.resolve(3)) .then(console.log); // 答案往左滑 输出顺序:1
  1. 起始阶段:Promise.resolve (1)
    代码是从一个初始 Promise 开始的,这个 Promise 直接以值 1 完成。
  2. 第一个 then (2)
    在 Promise 链里,.then() 方法需要接收一个函数作为参数。然而,此处传入的参数是数值 2,并非函数。这种情况下,.then() 会把它当作 then(() => undefined) 来处理,也就是实际上没有对 Promise 的值进行转换,所以值依旧是 1。
  3. 第二个 then (Promise.resolve (3))
    这里传入的参数是 Promise.resolve(3),但它不是一个函数。和上面的情况一样,.then() 会忽略这个 Promise,直接让原来的值 1 继续往下传递。
  4. 第三个 then (console.log)
    到了这一步,前面传递下来的值 1 会作为参数,被传递给 console.log 函数,于是控制台就会输出 1。
7
js
const p1 = new Promise((res, rej) => { setTimeout(() => { res('1'); }, 1000); }); const p2 = new Promise((res, rej) => { throw new Error('2'); }); console.log(p1); console.log(p2); setTimeout(() => { console.log(p1); console.log(p2); }, 2000); // 答案往左滑 输出顺序:<pending> <rejected 2> 2秒后 <fulfilled 1> <rejected 2>
这段代码需要注意的是,浏览器和node中执行的结果是不一样的,在Node.js中,如果存在未处理的Promise拒绝,默认情况下(特别是Node.js v15及以上)会抛出unhandledRejection事件,并可能导致进程退出。但在浏览器中,通常只会在控制台打印一个警告,而不会终止脚本。`
  1. 在浏览器中,就是标准答案,但是会有一个promise的报错提示,但程序不会终止
  2. 在node中,只会打印 <rejected 2> ,然后报错,程序退出执行。
8
js
Promise.resolve(1) .then((res) => { console.log(res); return 2; }) .catch((err) => { return 3; }) .then((res) => { console.log(res); }); // 答案往左滑 输出顺序:1 2
9
js
Promise.resolve() .then(() => { return new Error(1); }) .then((res) => { console.log(res); }) .catch((err) => { console.log(err); }); // 答案往左滑 输出顺序:Error: 1
10
js
const p1 = new Promise((res, rej) => { return p1; }); p1.catch((err) => { console.log(err); }); // 答案往左滑 输出顺序:ReferenceError: Cannot access 'p1' before initialization
这个挺难的,const 和 let 在被声明但是未初始化的时候会形成暂时性死区,这时访问这个变量就会报错,所以下面的catch可以捕获到错误。
11
js
Promise.reject(1) .then( (res) => { console.log('res', res); }, (err) => { console.log('err', err); }, ) .catch((err) => { console.log('catch', err); }); // 答案往左滑 输出顺序:err 1
12
js
Promise.resolve(1) .then((res) => { console.log(res); }) .finally(() => { console.log('finally'); }); Promise.resolve(2) .finally(() => { console.log('finally2'); return 3; }) .then((res) => { console.log(res); }); // 答案往左滑 输出顺序:// 1 finally2 finally 2
注意,finally 的返回值不会被采纳,但是如果执行时报错了,错误会被传递到后面的catch
13
js
function fn1(num) { return new Promise((r) => setTimeout( () => r(num, console.log(num)), 1000, ), ); } Promise.all([fn1(1), fn1(2), fn1(3)]).then( (res) => { console.log(res); }, ); // 答案往左滑 输出顺序:// 1 2 3 一秒后 [1, 2, 3]
我开始给出的答案是 undefined undefined undefined,把 num, console.log(num))想像成给一个变量赋值了。
reslove只接收第一个参数,其他都会的舍弃,但是会执行。
14
js
function fn1(num) { return new Promise((r) => setTimeout( () => r(num, console.log(num)), 1000, ), ); } function fn2(num) { return new Promise((res, rej) => setTimeout( () => rej(`error ${num}`, console.log(num)), 1000 * num, ), ); } Promise.all([fn1(1), fn2(4), fn1(3), fn2(2)]) .then((res) => console.log(res)) .catch((err) => console.log(err)); // 答案往左滑 输出顺序:// 1秒后 1 3, 2秒后 2 error 2, 4秒后 4
即使all中有错误产生了,数组中的其他promise依然会继续执行,promise产生了是无法取消执行的。
15
js
function runAsync(num) { return new Promise((resolve) => { setTimeout( () => resolve(num, console.log(num)), 1000, ); }); } Promise.race([ runAsync(1), runAsync(2), runAsync(3), ]) .then((res) => { console.log('res:', res); }) .catch((err) => { console.log('err:', err); }); // 答案往左滑 输出顺序:// 1秒后 1, res: 1, 2, 3
16
js
function runAsync(num) { return new Promise((resolve) => { setTimeout( () => resolve(num, console.log(num)), 1000, ); }); } function runReject(num) { return new Promise((resolve, reject) => { setTimeout( () => reject(num, console.log(num)), 1000 * num, ); }); } Promise.race([ runReject(0), runAsync(1), runAsync(2), runAsync(3), ]) .then((res) => { console.log('res:', res); }) .catch((err) => { console.log('err:', err); }); // 答案往左滑 输出顺序:// 0, err: 0, 1秒后 1, 2, 3
17
js
async function async1() { console.log('async1 start'); await async2(); console.log('async1 end'); } async function async2() { console.log('async2'); } async1(); console.log('script end'); // 答案往左滑 输出顺序:// async1 start, async2, script end, async1 end
18
js
async function async1() { console.log('async1 start'); await async2(); console.log('async1 end'); setTimeout(() => { console.log('async1 timer'); }, 0); } async function async2() { console.log('async2 start'); setTimeout(() => { console.log('async2 timer'); }, 0); console.log('async2 end'); } async1(); setTimeout(() => { console.log('outer timer'); }, 0); console.log('run'); // 答案往左滑 输出顺序:// async1 start, async2 start, async2 end, run, async1 end, async2 timer, outer timer, async1 timer
19
js
async function runAsync() { console.log('async start'); await new Promise((resolve) => { console.log('promise'); }); console.log('async end'); return 'async result'; } console.log('main start'); runAsync().then((res) => console.log(res)); console.log('main end'); // 答案往左滑 输出顺序:// main start, async start, promise, main end
20
js
async function runAsync() { console.log('async start'); await new Promise((resolve) => { console.log('promise'); resolve('promise resolve'); }).then((res) => console.log(res)); console.log('async end'); return 'async result'; } console.log('main start'); runAsync().then((res) => console.log(res)); console.log('main end'); // 答案往左滑 输出顺序:// main start, async start, promise, main end, promise resolve, async end, async result
21
js
async function runAsync() { console.log('async start'); await asyncFunc(); console.log('async end'); } async function asyncFunc() { console.log('do something'); } console.log('main start'); setTimeout(function () { console.log('timer'); }, 0); runAsync(); new Promise((resolve) => { console.log('promise'); resolve(); }).then(function () { console.log('promise then'); }); console.log('main end'); // 答案往左滑 输出顺序:// main start, async start, do something, promise, main end, async end, promise then, timer
22
js
async function runAsync() { await promiseFunc(); console.log('async'); return 'async result'; } async function promiseFunc() { return new Promise((resolve, reject) => { console.log('promise'); reject('error'); }); } runAsync().then((res) => console.log(res)); // 答案往左滑 输出顺序:// promise, Promise {<rejected>: 'error'}
23
js
const promiseWrapper = () => new Promise((resolve, reject) => { console.log('A'); let p = new Promise((resolve, reject) => { console.log('B'); setTimeout(() => { console.log('timer start'); resolve('timer succeed'); console.log('timer end'); }, 0); resolve('inner succeed'); }); resolve('outer succeed'); p.then((res) => { console.log(res); }); }); promiseWrapper().then((res) => { console.log(res); }); console.log(4); // 答案往左滑 输出顺序:// A, B, 4, inner succeed, outer succeed, timer start, timer end
24
js
const runAsync = async () => { console.log('async start'); setTimeout(() => { console.log('inner timer'); }, 2000); await new Promise((resolve) => { console.log('promise'); }); console.log('async end'); return 'async result'; }; console.log('main start'); runAsync().then((res) => console.log(res)); console.log('main end'); Promise.resolve('A') .then('then') .then(Promise.resolve('succeed')) .catch('catch') .then((res) => console.log(res)); setTimeout(() => { console.log('outer timer'); }, 1000); // 答案往左滑 输出顺序:// main start,async start, promise, main end, A, outer timer, inner timer
25
js
const myPromise = new Promise((resolve) => { setTimeout(() => { resolve('succeed3'); console.log('timer'); }, 0); resolve('succeed1'); resolve('succeed2'); }) .then((res) => { console.log(res); setTimeout(() => { console.log(myPromise); }, 1000); }) .finally((res) => { console.log('finally', res); }); // 答案往左滑 输出顺序:// succeed1, finally undefined, timer, Promise { undefined }
26
js
console.log('main start'); setTimeout(function () { console.log('timer1'); process.nextTick(function () { console.log('inner nextTick1'); }); new Promise(function (resolve) { console.log('inner promise1'); resolve(); }).then(function () { console.log('inner then1'); }); }); process.nextTick(function () { console.log('nextTick'); }); new Promise(function (resolve) { console.log('promise'); resolve(); }).then(function () { console.log('then'); }); setTimeout(function () { console.log('timer2'); process.nextTick(function () { console.log('inner nextTick2'); }); new Promise(function (resolve) { console.log('inner promise2'); resolve(); }).then(function () { console.log('inner then2'); }); }); // 答案往左滑 输出顺序:// main start, promise, nextTick, then, timer1, inner promise1, inner nextTick1, inner then1, timer2, inner promise2, inner nextTick2, inner then2
27
js
console.log('main start'); setTimeout(() => { console.log('timer1'); }); new Promise((resolve) => { console.log('promise'); resolve('promise succeed'); }).then((res) => console.log(res)); setTimeout(() => { console.log('timer'); new Promise((resolve) => { resolve('timer succeed'); }).then((res) => console.log(res)); }); setTimeout(() => { console.log('timer2'); }); console.log('main end'); // 答案往左滑 输出顺序:// main start, promise, main end, promise succeed, timer1, timer, timer succeed, timer2
28
js
console.log('main start'); setTimeout(() => { console.log('timer1'); Promise.resolve().then(() => { console.log('inner then'); }); }); new Promise((resolve, reject) => { console.log('promise'); resolve('succeed'); }).then((data) => { console.log('then'); }); setTimeout(() => { console.log('timer2'); }); console.log('main end'); // 答案往左滑 输出顺序:
main start
promise
main end
then
timer1
inner then
timer2
29
js
Promise.resolve() .then(() => { console.log('then1'); throw 'error'; }) .then(() => { console.log('then2'); }) .catch(() => { console.log('catch1'); throw 'error'; }) .then(() => { console.log('then3'); }) .catch(() => { console.log('catch2'); }) .then(() => { console.log('then4'); }); // 答案往左滑 输出顺序:
then1
catch1
catch2
then4
30
js
console.log('main start'); setTimeout(function () { console.log('timer'); }, 100); new Promise(function (resolve) { console.log('promise start'); resolve(); console.log('promise end'); }).then(function () { console.log('then start'); new Promise((resolve, reject) => { console.log('inner promise'); setTimeout(() => { console.log('inner timer'); }, 10); }); }); console.log('main end'); // 答案往左滑 输出顺序:
main start
promise start
promise end
main end
then start
inner promise
inner timer
timer