JS异步编程题

思考以下JS异步编程题中的执行顺序和结果:

async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
}
async function async2() {
  setTimeout(() => {
    console.log('timer')
  }, 0)
  console.log("async2");
}
async1();
console.log("start")

结果如下:

async1 start

async2

start

async1 end

timer

async function async1 () {
  console.log('async1 start');
  await new Promise(resolve => {
    console.log('promise1')
    resolve('promise resolve')
  })
  console.log('async1 success');
  return 'async1 end'
}
console.log('srcipt start')
async1().then(res => {
  console.log(res)
})
new Promise(resolve => {
  console.log('promise2')
  setTimeout(() => {
    console.log('timer')
  })
})

结果如下:

srcipt start

async1 start

promise1

promise2

async1 success

async1 end

timer

async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
}

async function async2() {
  console.log("async2");
}

console.log("script start");

setTimeout(function() {
  console.log("setTimeout");
}, 0);

async1();

new Promise(function(resolve) {
  console.log("promise1");
  resolve();
}).then(function() {
  console.log("promise2");
});
console.log('script end')

结果如下:

script start

async1 start

async2

promise1

script end

async1 end

promise2

setTimeout

async function testSometing() {
  console.log("执行testSometing");
  return "testSometing";
}

async function testAsync() {
  console.log("执行testAsync");
  return Promise.resolve("hello async");
}

async function test() {
  console.log("test start...");
  const v1 = await testSometing();
  console.log(v1);
  const v2 = await testAsync();
  console.log(v2);
  console.log(v1, v2);
}

test();

var promise = new Promise(resolve => {
  console.log("promise start...");
  resolve("promise");
});
promise.then(val => console.log(val));

console.log("test end...");

结果如下:

test start…

执行testSometing

promise start…

test end…

testSometing

执行testAsync

promise

hello async

testSometing hello async

async function async1 () {
  await async2();
  console.log('async1');
  return 'async1 success'
}
async function async2 () {
  return new Promise((resolve, reject) => {
    console.log('async2')
    reject('error')
  })
}
async1().then(res => console.log(res))

结果如下:

‘async2’

Uncaught (in promise) error

const first = () => (new Promise((resolve, reject) => {
    console.log(3);
    let p = new Promise((resolve, reject) => {
        console.log(7);
        setTimeout(() => {
            console.log(5);
            resolve(6);
            console.log(p)
        }, 0)
        resolve(1);
    });
    resolve(2);
    p.then((arg) => {
        console.log(arg);
    });
}));
first().then((arg) => {
    console.log(arg);
});
console.log(4);

结果如下:

3

7

4

1

2

5

Promise <fulfilled>1

var a;
var b = new Promise((resolve, reject) => {
  console.log('promise1');
  setTimeout(() => {
    resolve();
  }, 1000);
})
  .then(() => {
    console.log('promise2');
  })
  .then(() => {
    console.log('promise3');
  })
  .then(() => {
    console.log('promise4');
  });

a = new Promise(async (resolve, reject) => {
  console.log(a);
  await b;
  console.log(a);
  console.log('after1');
  await a;
  resolve(true);
  console.log('after2');
});

console.log('end');

结果如下:

promise1

undefined

end

promise2

promise3

promise4

Promise { <pending> }

after1

new Promise((resolve, reject) => {
    resolve(2) 
    new Promise((resolve, reject) => {
        resolve(5)
    }).then((v) => {
        console.log(v)
    })
}).then((v) => {
    console.log(v)
})


new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(2)
        new Promise((resolve, reject) => {
      resolve(5)
    }).then((v) => {
      console.log(v)
    })
    })
}).then((v) => {
    console.log(v)
})

结果如下:

5

2

2

5

async function async1() {
  console.log('async1 start');
  await async2();
  console.log('async1 end');
}
async function async2() {
  console.log('async2');
}

console.log('script start');

setTimeout(function () {
  console.log('setTimeout');
}, 0);

async1();

new Promise(function (resolve) {
  console.log('promise1');
  resolve();
}).then(function () {
  console.log('promise2');
});
console.log('script end');

结果如下:

script start

async1 start

async2

promise1

script end

async1 end

promise2

setTimeout

console.log(1);
setTimeout(() => {
    console.log(2);
    process.nextTick(() => {
        console.log(3);
    });
    new Promise((resolve) => {
        console.log(4);
        resolve();
    }).then(() => {
        console.log(5);
    });
});
new Promise((resolve) => {
    console.log(7);
    resolve();
}).then(() => {
    console.log(8);
});
process.nextTick(() => {
    console.log(6);
});
setTimeout(() => {
    console.log(9);
    process.nextTick(() => {
        console.log(10);
    });
    new Promise((resolve) => {
        console.log(11);
        resolve();
    }).then(() => {
        console.log(12);
    });
});

分析:

事件循环相关基础

  • 主线程先执行所有同步代码。
  • 每一个 tick(事件循环)分为:
  • 同步代码
  • nextTick 队列(process.nextTick,在微任务队列之前,优先级最高)
  • 微任务队列(Promise.then,queueMicrotask 等)
  • 宏任务队列(setTimeout、setInterval、IO 等)

逐步分析执行过程

1. 同步代码优先执行

console.log(1); // 打印 1
setTimeout(...); // 加入宏任务队列1
new Promise(...); // 打印 7
process.nextTick(...); // 加入 nextTick 队列
setTimeout(...); // 加入宏任务队列2

执行顺序:

  • console.log(1) 打印 1
  • setTimeout(...) 加入宏任务队列1
  • new Promise(...) 执行构造函数,打印 7,resolve() 后 .then(...) 加入微任务队列
  • process.nextTick(...) 加入 nextTick 队列
  • setTimeout(...) 加入宏任务队列2

2. 主线程执行完毕,处理 nextTick 队列

只有一个:

  • console.log(6) 打印 6

3. 处理 微任务队列(Promise.then)

只有一个:

  • console.log(8) 打印 8

此时同步阶段结束,输出为:1 7 6 8

4. 进入 宏任务队列(setTimeout)

宏任务1(第一个 setTimeout)

console.log(2);
process.nextTick(() => { console.log(3); });
new Promise((resolve) => {
    console.log(4);
    resolve();
}).then(() => {
    console.log(5);
});
  • console.log(2) 打印 2
  • process.nextTick(...) 加入 nextTick 队列
  • console.log(4) 打印 4
  • resolve() 后 .then(...) 加入微任务队列

宏任务1内同步结束,输出:2 4

先处理 nextTick:

  • console.log(3) 打印 3

再处理微任务:

  • console.log(5) 打印 5

宏任务1阶段输出:2 4 3 5

宏任务2(第二个 setTimeout)

console.log(9);
process.nextTick(() => { console.log(10); });
new Promise((resolve) => {
    console.log(11);
    resolve();
}).then(() => {
    console.log(12);
});
  • console.log(9) 打印 9
  • process.nextTick(...) 加入 nextTick 队列
  • console.log(11) 打印 11
  • resolve() 后 .then(...) 加入微任务队列

宏任务2内同步结束,输出:9 11

先处理 nextTick:

  • console.log(10) 打印 10

再处理微任务:

  • console.log(12) 打印 12

宏任务2阶段输出:9 11 10 12

最终输出顺序:

1 7 6 8 2 4 3 5 9 11 10 12

 

原创文章,作者:czhdawn,如若转载,请注明出处:https://www.czhdawn.cn/archives/4959

(0)
czhdawn的头像czhdawn
上一篇 2025年8月7日 14:39
下一篇 2025年8月12日 19:01

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注