何不知道document.createElement('img')将完成同步?

时间:2018-09-27 12:17:23

标签: javascript asynchronous promise async-await

我试图了解异步/等待并陷入示例问题。

我知道如果我有2个功能,如:

f1(//console.log(1) after 5 sec)
f2(//console.log(2) after 1 sec)

结果将是:

2
1

好,现在我们有了异步功能的官方示例

async function showAvatar() {
      // read our JSON
      let response = await fetch('/article/promise-chaining/user.json');
      let user = await response.json();

      // show the avatar
      let img = document.createElement('img'); //but why they sure it will completed sync and not async and document.body.append will not append not yet existing img?
      document.body.append(img);
    }

    showAvatar();

但是document.createElement('img')的功能也像f1一样,可能会滞后,但是由于某些原因,我们没有在其上使用await吗? 为什么?

1 个答案:

答案 0 :(得分:1)

  

但是document.createElement('img')的功能也像f1一样,可能会滞后,但是由于某些原因,我们没有在其上使用await吗?为什么呢?

这是因为await是保留关键字,只能在async function中使用。不在外面。 await运算符的动机是等待承诺。所以当你做

await foo();

然后它仅在foo()返回一个Promise对象时起作用。

以下语句,

document.createElement('img');

不返回Promise对象,而是返回HTMLImageElement。那不是Promise对象,因此您不能使用await等待它。有一个onload事件,您可以使用该事件在将图像加载到其中后执行操作:

const img = document.createElement('img');
img.onload = _ => console.log('after load');
img.src = 'url';

当处理最后一条语句时,浏览器正在从给定的url中检索信息。完成加载信息后,它将调用.onload来指示完成加载图像数据。

编辑:

可以运行

async function loadImage() {
  const img = await document.createElement('img');
  ...
} 

没有错误,因为如果await不是Promise对象,则会将结果转换为解析的Promise。以下报价摘自MDN:

  

如果await运算符后面的表达式的值不是Promise,则将其转换为解析的Promise。 source

因此,返回的HTMLImageElement通过Promise.resolve(...)调用转换为Promise对象。然后await然后按照指示处理promise对象。