对JavaScript Promise/async/await的一些理解

本文探讨了Promise构造函数中executor的同步执行、Promise.then的异步执行时机、await的阻塞特性以及全局已解析Promise的影响。通过示例解释了await如何影响async函数内的代码执行,并分析了更新DOM UI与Promise的关系。同时提到了TensorFlow.js的kernel profile相关话题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

new Promise executor的执行时机

new Promise里面通常会传入一个function参数。直觉上,传入的function,应该类似于callback,属于被异步调用的。但是实际上,它是同步被执行的。也就是说它是在Promise的构造函数里面被执行的。文献
https://javascript.info/promise-basics提到这个function有个专有的名字:executor:
The function passed to new Promise is called the executor. When new Promise is created, the executor runs automatically.
下面看看一个http request(https://developers.google.com/web/fundamentals/primers/promises)。new promise里面的XMLHttpRequest是即时发出的。所谓异步,体现在Promise.then的执行,是在onload/resolve之后发生的。

function get(url) {
  // Return a new promise.
  return new Promise(function(resolve, reject) {
    // Do the usual XHR stuff
    console.log("In Promise's executor");
    var req = new XMLHttpRequest();
    req.open('GET', url);

    req.onload = function() {
      // This is called even on 404 etc
      // so check the status
      if (req.status == 200) {
        // Resolve the promise with the response text
        resolve(req.status);
      }
      else {
        // Otherwise reject with the status text
        // which will hopefully be a meaningful error
        reject(Error(req.statusText));
      }
    };

    // Handle network errors
    req.onerror = function() {
      reject(Error("Network Error"));
    };

    // Make the request
    req.send();
  });
}
console.log("Begin");
get('https://jsfiddle.net/').then(function(response) {
  console.log("Success!", response);
}, function(error) {
  console.error("Failed!", error);
})

console.log("End");
Begin
In Promise's executor
End
Success! 200

Promise.then的执行时机

Promise.then里面的函数,其执行时机是主线程结束后的某个时间。
关于promise的执行有两种猜测:

  • chromium里面维护了多个线程,操作DOM所在的JS线程叫主线程。此外为了实现异步,准备了一个线程池,这个线程池,就是用于执行这里的promise的任务。
  • (作者更倾向于这个)Promise和操作DOM的JS都位于同一个主线程(我理解JS是单线程的,Promise也并没有和WebWorker绑定)。在Chromium内部,每次碰到Promise,都会给主线程post 一个task。chromium内部线程机制是,post task是在下一个时钟周期开始执行里面的任务的(每次时钟周期开始会切换任务队列)。所以我们能够观测到,所有Promise,都是在主线程把所有事情做完后的某个时机,才开始逐个被resolve的。要验证Promise是否是在主线程的方法是:在Promise里面执行一个超长的任务,看看网页UI是否失去响应(TODO)。
var promise1 = new Promise(function(resolve, reject) {
  // 输出1
  console.log("Ins
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值