From 65cc6eabd71b1bceccf6fd3d3d4970c2955f3784 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Thu, 10 Dec 2020 08:37:18 -0500 Subject: dump 2020-12-10 --- .../async_await/index.html" | 4 +- .../choosing_the_right_approach/index.html" | 12 ++--- .../promises\350\257\255\346\263\225/index.html" | 52 +++++++++++++--------- .../\347\256\200\344\273\213/index.html" | 2 +- 4 files changed, 40 insertions(+), 30 deletions(-) (limited to 'files/zh-cn/learn/javascript') diff --git "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/async_await/index.html" "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/async_await/index.html" index ae79af9899..739ab63602 100644 --- "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/async_await/index.html" +++ "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/async_await/index.html" @@ -323,11 +323,11 @@ timeTest().then(() => {

您必须仔细测试您的代码,并在性能开始受损时牢记这一点。

-

另一个小小的不便是你必须将期待已久的promise封装在异步函数中。

+

另一个小小的不便是你必须将等待执行的promise封装在异步函数中。

Async/await 的类方法

-

最后值得一提的是,我们可以在类/对象方法前面添加async,以使它们返回promises,并await它们内部的promises。查看 ES class code we saw in our object-oriented JavaScript article,然后使用异步方法查看我们的修改版本:

+

最后值得一提的是,我们可以在类/对象方法前面添加async,以使它们返回promises,并await它们内部的promises。查看 ES class code we saw in our object-oriented JavaScript article,然后查看使用异步方法的修改版本:

class Person {
   constructor(first, last, age, gender, interests) {
diff --git "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/choosing_the_right_approach/index.html" "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/choosing_the_right_approach/index.html"
index f11113420e..276d815b85 100644
--- "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/choosing_the_right_approach/index.html"
+++ "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/choosing_the_right_approach/index.html"
@@ -7,7 +7,7 @@ translation_of: Learn/JavaScript/Asynchronous/Choosing_the_right_approach
 
 
{{PreviousMenu("Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}
-

为了完成这个模块,我们将简要讨论我们在整个过程中讨论的不同编码技术和功能,看看你应该使用哪一个,并提供适当的常见陷阱的建议和提醒。随着时间的推移,我们可能会添加到此资源中。

+

为了完成这个模块,我们将简要讨论之前章节谈论过编码技术和功能,看看你应该使用哪一个,并提供适当的建议和提醒。随着时间的推移,我们可能会添加到此资源中。

@@ -24,7 +24,7 @@ translation_of: Learn/JavaScript/Asynchronous/Choosing_the_right_approach

异步回调

-

通常在旧式API中找到,涉及将函数作为参数传递给另一个函数,然后在异步操作完成时调用该函数,以便回调可以依次对结果执行某些操作。这是promise的先导;它不那么高效或灵活。仅在必要时使用。

+

通常在旧式API中找到,涉及将函数作为参数传递给另一个函数,然后在异步操作完成时调用该函数,以便回调可以依次对结果执行某些操作。这是promise的前身;它不那么高效或灵活。仅在必要时使用。

@@ -76,7 +76,7 @@ loadAsset('coffee.jpg', 'blob', displayImage);
Useful for...
diff --git "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/promises\350\257\255\346\263\225/index.html" "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/promises\350\257\255\346\263\225/index.html" index a817a71d79..665bda8129 100644 --- "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/promises\350\257\255\346\263\225/index.html" +++ "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/promises\350\257\255\346\263\225/index.html" @@ -188,7 +188,7 @@ translation_of: Learn/JavaScript/Asynchronous/Promises

好的,我们还需要做点额外的工作。Fetch promises 不会产生 404 或 500错误,只有在产生像网路故障的情况时才会不工作。总的来说,Fetch promises 总是成功运行,即使response.ok 属性是 false。为了产生404错误,我们需要判断 response.ok ,如果是 false,抛出错误,否则返回 blob。就像下面的代码这样做。

-
let promise2 = promise.then(response => {
+
let promise2 = promise.then(response => {
   if (!response.ok) {
     throw new Error(`HTTP error! status: ${response.status}`);
   } else {
@@ -204,7 +204,7 @@ translation_of: Learn/JavaScript/Asynchronous/Promises
 
 

6. 现在让我们填写执行程序函数的主体。在花括号内添加以下行:

-
let objectURL = URL.createObjectURL(myBlob);
+
let objectURL = URL.createObjectURL(myBlob);
 let image = document.createElement('img');
 image.src = objectURL;
 document.body.appendChild(image);
@@ -237,8 +237,14 @@ document.body.appendChild(image);

这是写出来的一种非常简便的方式;我们故意这样做是为了帮助你清楚地了解发生了什么。如本文前面所示,你可以将.then()块(以及.catch()块)链接在一起。上面的代码也可以这样写(参阅GitHub上的simple-fetch-chained.html ):

-
fetch('coffee.jpg')
-.then(response => response.blob())
+
fetch('coffee.jpg')
+.then(response => {
+  if (!response.ok) {
+    throw new Error(`HTTP error! status: ${response.status}`);
+  } else {
+    return response.blob();
+  }
+})
 .then(myBlob => {
   let objectURL = URL.createObjectURL(myBlob);
   let image = document.createElement('img');
@@ -247,7 +253,7 @@ document.body.appendChild(image);
}) .catch(e => { console.log('There has been a problem with your fetch operation: ' + e.message); -});
+});

请记住,履行的promise所返回的值将成为传递给下一个 .then() 块的executor函数的参数。

@@ -279,9 +285,9 @@ document.body.appendChild(image);
... }); -

如果它们都实现,那么一个包含所有这些结果的数组将作为.all()的参数传给其链接的.then()块的执行器函数。如果传递给Promise.all()的任何promise都拒绝,整个块将拒绝

+

如果它们都实现,那么数组中的结果将作为参数传递给.then()块中的执行器函数。如果传递给Promise.all()的任何一个 promise 拒绝,整个块将拒绝

-

这非常有用。想象一下,我们正在获取信息以在内容上动态填充页面上的UI功能。在许多情况下,接收所有数据然后才显示完整内容,而不是显示部分信息是有意义的。

+

这非常有用。想象一下,我们正在获取信息以在内容上动态填充页面上的UI功能。在许多情况下,接收所有数据然后才显示完整内容,而不是显示部分信息。

让我们构建另一个示例来展示这一点。

@@ -323,11 +329,11 @@ Promise.all([a, b, c]).then(values => {

这看起来有点复杂,所以让我们一步一步地完成它:

    -
  1. 首先,我们定义函数,向它传递一个URL和一个表示它正在获取的资源类型的字符串。
  2. -
  3. 在函数体内部,我们有一个类似于我们在第一个例子中看到的结构 - 我们调用fetch()函数来获取指定URL处的资源,然后将其链接到另一个返回解码(或“read”)的promise。 )响应body。这始终是前一个示例中的blob()方法。
  4. +
  5. 首先,我们定义函数,向它传递一个URL和字符串,这个字符串表示资源类型。
  6. +
  7. 在函数体内部,我们有一个类似于我们在第一个例子中看到的结构 - 我们调用fetch()函数来获取指定URL处的资源,然后将其链接到另一个 promise ,它解码(或“read”)响应body。这是前一个示例中的blob()方法。
  8. 但是,这里有两处不同:
      -
    • 首先,我们返回的第二个promise会因类型值的不同而不同。在执行函数内部,我们包含一个简单的if ... else if语句,根据我们需要解码的文件类型返回不同的promise(在这种情况下,我们可以选择blobtext,但这很容易扩展这个以处理其他类型)。
    • +
    • 首先,我们返回的第二个promise会因类型值的不同而不同。在执行函数内部,我们包含一个简单的if ... else if语句,根据我们需要解码的文件类型返回不同的promise(在这种情况下,我们可以选择blobtext,而且很容易扩展这个以处理其他类型)。
    • 其次,我们在fetch()调用之前添加了return关键字。它的作用是运行整个链,然后运行最终结果(即blob()text()返回的promise作为我们刚刚定义的函数的返回值)。实际上,return语句将结果从链返回到顶部。
  9. @@ -352,7 +358,7 @@ let description = fetchAndDecode('description.txt', 'text'); }); -

    你可以看到它需要一个包含promises作为参数的数组。执行者只有在所有三个promises的状态成为resolved时才会运行;当发生这种情况时,它将传递一个数组,其中包含来自各个promise(即解码的响应主体)的结果,类似于 [coffee-results, tea-results, description-results].

    +

    你可以看到它需要一个包含promises作为参数的数组。执行者只有在所有三个promises的状态成为resolved时才会运行;当发生这种情况时,它将被传入一个数组,其中包含来自各个promise(即解码的响应主体)的结果,类似于 [coffee-results, tea-results, description-results].

  10. 最后,在执行程序中添加以下内容。这里我们使用一些相当简单的同步代码将结果存储在单独的变量中(从blob创建对象URL),然后在页面上显示图像和文本。

    @@ -407,7 +413,7 @@ document.body.appendChild(para); runFinalCode(); }); -

    在最近的现代浏览器中,.finally() 方法可用,它可以链接到常规promise链的末尾,允许你减少代码重复并更优雅地执行操作。上面的代码现在可以写成如下:

    +

    在现代浏览器中,.finally() 方法可用,它可以链接到常规promise链的末尾,允许你减少代码重复并更优雅地执行操作。上面的代码现在可以写成如下:

    myPromise
     .then(response => {
    @@ -422,12 +428,16 @@ document.body.appendChild(para);

    有关一个真实示例,请查看我们的promise-finally.html demo(另请参阅source code)。这与我们在上面部分中看到的Promise.all()演示完全相同,除了在fetchAndDecode()函数中我们将finally()调用链接到链的末尾:

    -
    function fetchAndDecode(url, type) {
    +
    function fetchAndDecode(url, type) {
       return fetch(url).then(response => {
    -    if(type === 'blob') {
    -      return response.blob();
    -    } else if(type === 'text') {
    -      return response.text();
    +    if(!response.ok) {
    +      throw new Error(`HTTP error! status: ${response.status}`);
    +    } else {
    +      if(type === 'blob') {
    +        return response.blob();
    +      } else if(type === 'text') {
    +        return response.text();
    +      }
         }
       })
       .catch(e => {
    @@ -436,7 +446,7 @@ document.body.appendChild(para);
    .finally(() => { console.log(`fetch attempt for "${url}" finished.`); }); -}
    +}

    这会将一条简单的消息记录到控制台,告诉我们每次获取尝试的时间。

    @@ -454,7 +464,7 @@ document.body.appendChild(para);

    可以使用Promise() 构造函数构建自己的promise。当你需要使用现有的旧项目代码、库或框架以及基于现代promise的代码时,这会派上用场。比如,当你遇到没有使用promise的旧式异步API的代码时,你可以用promise来重构这段异步代码。

    -

    让我们看一个简单的示例来帮助你入门 —— 这里我们使用promise包装一个setTimeout()调用 - 它会在两秒后运行一个函数,该函数将用字符串“Success!”,解析当前promise(调用链接的resolve()),。

    +

    让我们看一个简单的示例来帮助你入门 —— 这里我们用 promise 包装一了个setTimeout()它会在两秒后运行一个函数,该函数将用字符串“Success!”,解析当前promise(调用链接的resolve())。

    let timeoutPromise = new Promise((resolve, reject) => {
       setTimeout(function(){
    @@ -462,7 +472,7 @@ document.body.appendChild(para);
    }, 2000); }); -

    resolve()reject()是用来实现拒绝新创建的promise的函数。此处,promise实现了字符串“Success!”。

    +

    resolve()reject()是用来实现拒绝新创建的promise的函数。此处,promise 成功运行通过显示字符串“Success!”。

    因此,当你调用此promise时,可以将.then()块链接到它的末尾,它将传递给.then()块一串“Success!”。在下面的代码中,我们显示出该消息:

    @@ -534,7 +544,7 @@ document.body.appendChild(para);

    一个更真实的例子

    -

    上面的例子是故意做得简单,以使概念易于理解,但它并不是实际上完全同步。异步性质基本上是使用setTimeout()伪造的,尽管它仍然表明promises对于创建具有合理的操作流程,良好的错误处理等的自定义函数很有用

    +

    上面的例子是故意做得简单,以使概念易于理解,但它并不是实际上完全异步。异步性质基本上是使用setTimeout()伪造的,尽管它仍然表明promises对于创建具有合理的操作流程,良好的错误处理等的自定义函数很有用

    我们想邀请你学习的一个例子是Jake Archibald's idb library,它真正地显示了Promise()构造函数的有用异步应用程序。这采用了 IndexedDB API,它是一种旧式的基于回调的API,用于在客户端存储和检索数据,并允许你将其与promises一起使用。如果你查看main library file,你将看到我们在上面讨论过的相同类型的技术。以下块将许多IndexedDB方法使用的基本请求模型转换为使用promise:

    diff --git "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\347\256\200\344\273\213/index.html" "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\347\256\200\344\273\213/index.html" index c218d064ca..1792c0e086 100644 --- "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\347\256\200\344\273\213/index.html" +++ "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\347\256\200\344\273\213/index.html" @@ -229,7 +229,7 @@ console.log("all done");

    要查看实际情况,请尝试获取示例的本地副本,并将第三个console.log()调用更改为以下命令:

    -
    console.log ('All done! ' + image + 'displayed.');
    +
    console.log ('All done! ' + image.src + 'displayed.');

    此时控制台将会报错,而不会显示第三个 console.log 的信息:

    -- cgit v1.2.3-54-g00ecf
Useful for...