Did you use some JavaScript to make your web app dynamic? That’s the common usage for this language, but there is far more waiting for you.

您是否使用一些JavaScript来使您的Web应用程序动态化? 这是该语言的常用用法,但还有更多等待您的机会。

After reading the popular book series You Don’t Know JS by Kyle Simpson, I realised I didn’t know JS before. The JavaScript community considers this series as one of the references for the language. It’s thick but complete. This series is an invaluable (and free) ally to help you sharpen your skills.

在读完凯尔·辛普森( Kyle Simpson)的畅销书系列《 你不懂JS》之后,我意识到我以前并不了解JS。 JavaScript社区将此系列视为该语言的参考之一。 它很厚但是很完整。 本系列是帮助您提高技能的宝贵(免费)盟友。

In this article, I gathered the most important insights out of it for you. From the simple stuff to the tough (this keyword and promises). I didn’t quote the book but preferred to build my own examples. Consider this as an introduction to the book series.

在本文中,我为您收集了最重要的见解。 从简单的东西到强硬(此关键字和Promise)。 我没有引用这本书,而是更喜欢建立自己的例子。 将此视为本书系列的简介。

If you learned JavaScript at school like me, I bet you learned Java first. Be careful, learning JavaScript isn’t about mimicing Java. It doesn’t work like that — you must learn it as new language.

如果您像我一样在学校里学习过JavaScript,那么我敢打赌,您会首先学习Java。 请注意,学习JavaScript并不是要模仿Java。 它不是那样工作的-您必须以新语言学习它。

第1课-逻辑运算符 (LESSON 1 — Logical operators)

In many languages, expressions which implement logical operators such as AND and OR return a boolean value. Instead, JavaScript returns one of the two operands as explained in this ECMAScript specification note.

在许多语言中,实现逻辑运算符(例如ANDOR)的表达式返回布尔值。 而是,JavaScript返回此ECMAScript规范说明中所述的两个操作数之一。

With both operators, it returns the first operand which stops the evaluation. Give it a try by setting foo or bar to the false boolean value. Also, if you don’t include any parenthesis, the AND operator has priority over OR.

使用这两个运算符,它将返回第一个操作数,该操作数将停止评估。 通过将foobar设置为false布尔值来尝试一下。 另外,如果您不包含任何括号,则AND运算符的优先级高于OR

It first evaluates foo && foo.bar as if it’s between parenthesis. You can say AND has precedence over OR.

它首先评估foo && foo.bar ,就好像它在括号之间。 您可以说AND优先于OR

Given that the OR operator returns the first operand which fulfills it, you can use it to set a default value for empty or not defined variables. It was the preferred way to define default function parameters before ES6.

假定OR运算符返回满足它的第一个操作数,则可以使用它为空变量或未定义变量设置默认值。 这是在ES6之前定义默认功能参数的首选方法。

Another use case for those logical operators is to avoid if-else blocks and ternary expressions:

这些逻辑运算符的另一个用例是避免if-else块和三元表达式:

Here are equivalencies for ternary expressions:

以下是三元表达式的等效项:

  • a || b is equivalent to a ? a : b

    a || b a || b等于a ? a : b a ? a : b

  • a && b is equivalent to a ? b : a

    a && b等于a ? b : a a ? b : a

第2课-类型转换 (LESSON 2 — Type conversion)

Besides functions such as valueOf, JavaScript provides for type conversion. It exists as aother way to convert variables types.

除了valueOf功能外,JavaScript还提供类型转换 。 它是转换变量类型的另一种方式。

  • Cast occurs at compilation time and uses the explicit cast operator

    强制转换发生在编译时,并使用显式强制转换运算符

  • Coercion occurs at runtime and often with an implicit syntax

    强制发生在运行时,并且通常使用隐式语法

Implicit coercion is the harder type of conversion to see, so developers often avoid using them. Yet, it’s good to know some common implicit coercions. Here are examples for String and Boolean.

隐式强制转换是较难看到的转换类型,因此开发人员通常避免使用它们。 但是,了解一些常见的隐式强制是很好的。 以下是StringBoolean示例。

Another useful but rarely used operator is ~, an equivalent to the -(x+1) operation. It’s helpful to detect the common sentinel value -1.

另一个有用但很少使用的运算符是~ ,它等效于-(x+1)操作。 检测公共前哨值 -1很有帮助。

第3课-虚假的价值观 (LESSON 3 — Falsy values)

Conditions are one of the basic structures in programming and we use them a lot. By the way, the legend says artificial intelligence programs are full of if. It’s important to know how it behaves in any programming language.

条件是编程中的基本结构之一,我们经常使用它们。 顺便说一句,传说说人工智能程序充满了if 。 重要的是要知道它在任何编程语言中的行为。

Values given to a condition are either considered falsy or truthy. The ECMAScript specification comes with a curated list of falsy values:

赋予条件的值被认为是虚假的真实的 。 ECMAScript规范附带伪造值的精选列表:

  • '’ empty string

    ''空字符串

  • undefined

    undefined

  • null

    null

  • false boolean value

    false布尔值

  • 0 number value

    0号值

  • -0 number value

    -0数值

  • NaN not a number value

    NaN不是数字值

Experiment yourself with the following snippet:

尝试以下代码段:

Any other value not in the list is truthy. For instance, be careful about {} (empty literal object), [] (empty array) and 'false' (false string) which all are true.

列表中未包含的任何其他值都是真实的。 例如,请注意{} (空文字对象), [] (空数组)和'false' (假字符串)都为true

Combined with logical operators, you can call a function only if a value is truthy without using a if.

结合逻辑运算符,仅当值是真值时才可以调用函数,而无需使用if

第4课-范围和IIFE (LESSON 4 — Scope and IIFE)

The first time you wrote some JavaScript, someone probably told you to use the following notation because “it works better”.

第一次编写JavaScript时,可能有人告诉您使用以下表示法,因为“它会更好”

It does the same as declaring a regular function and then calling it immediately.

它的作用与声明常规函数然后立即调用它相同。

This notation is an IIFE, it stands for Immediately Invoked Function Expression. And it doesn’t work better but it prevents variable collisions.

此表示法是IIFE ,它表示立即调用函数表达式 。 它并不能更好地工作,但是可以防止变量冲突。

foo variable from a script tag is magically attached to the window. Pretty interesting when you know libraries and frameworks define their own variables using the same technique.

脚本标签中的 foo变量神奇地附加到了窗口上。 当您知道库和框架使用相同的技术定义它们自己的变量时,这非常有趣。

Actually the scope of variables defined with the var keyword isn’t bound to all blocks. Those blocks are code parts delimited with curly braces as in if and for expressions, for instance.

实际上,用var关键字定义的变量的作用域并不限于所有块。 那些块是用大括号定界的代码部分,例如在iffor表达式中。

Only function and try-catch blocks can restrict var's scope. Even if-else blocks and for loops can’t do it.

只有functiontry-catch块可以限制var的范围。 即使if-else块和for循环也无法做到。

Using IIFE provides a way to hide variables from the outside and restrict their scope. Thus, no one can alter the business logic by changing the window’s variable values.

使用IIFE提供了一种从外部隐藏变量并限制其范围的方法。 因此,没有人可以通过更改窗口的变量值来更改业务逻辑。

ES6 comes with the let and const keyword. Variables using these keywords are bound to blocks defined with curly braces.

ES6带有letconst关键字。 使用这些关键字的变量绑定到用花括号定义的块。

第5课-对象和地图 (LESSON 5 — Object and maps)

Objects help gather variables with the same topic under a unique variable. You end with an object containing many properties. There are two syntaxes to access an object property: dot and array syntax.

对象帮助在唯一变量下收集具有相同主题的变量。 您以包含许多属性的对象结束。 有两种访问对象属性的语法:点和数组语法。

The array syntax seems to be the best solution to create maps but it’s not. In this setup, keys must be strings. If not it’s coerced into a string. For instance, any object is coerced as [object Object] key.

数组语法似乎是创建映射的最佳解决方案,但事实并非如此。 在此设置中,键必须是字符串。 如果不是,则将其强制为字符串。 例如,任何对象都被强制为[object Object]键。

// From here, examples are a bit lengthy.
// I’ll use emebeded code so you can copy/paste and try yourself!let map = {};
let x = { id: 1 },y = { id: 2 };map[x] = 'foo';
map[y] = 'bar';console.log(map[x], map[y]); // 'bar', 'bar'

From here, examples are a bit lengthy. I’ll use gists so you can copy/paste and try yourself!

从这里开始,例子有些冗长。 我将使用要点,以便您可以复制/粘贴并尝试一下!

In reality, this map got only one value under the [object Object] key. First, its value is 'foo' and then it becomes 'bar'.

实际上,此映射在[object Object]键下只有一个值。 首先,其值为'foo' ,然后变为'bar'

To avoid this issue, use the Map object introduced in ES6. Yet be careful, the lookup operation to get a value from a key is using a strict equality.

为避免此问题,请使用ES6中引入的Map对象 。 但是要小心,从键获取值的查找操作是使用严格的等式 。

var map = new Map();
map.set(x, 'foo');
map.set(y, 'bar');console.log(map.get(x), map.get(y)); // 'foo', 'bar'// undefined, undefined
console.log(map.get({ id: 1 }, map.get({ id: 2 });

This detail only matters for complex variables such as objects. Because two objects with the same content won’t match with strict equality. You must use the exact variable you put as a key to retrieve your value from the map.

此细节仅对复杂变量(例如对象)重要。 因为具有相同内容的两个对象不会严格相等地匹配。 您必须使用输入的确切变量作为键,才能从地图中检索值。

第6课-这是什么? (LESSON 6 — What’s this?)

The this keyword is used in languages built with classes. Usually, this (and its sibling self) refer to the current instance of the class being used. Its meaning doesn’t change a lot in OOP. But, JavaScript didn’t have classes prior to ES6 (although it still had the this keyword).

在使用类构建的语言中使用this关键字。 通常, this (及其同级self )是指所使用类的当前实例。 在OOP中它的含义没有太大的变化。 但是,JavaScript在ES6之前没有类(尽管它仍然具有this关键字)。

The value of this in JavaScript is different according to the context. To determine its value, you must first inspect the call-site of the function where you’re using it.

JavaScript中的this值根据上下文而有所不同。 要确定其值,您必须首先检查使用它的函数的调用位置

function foo () {console.log( this.a );
}// #1: Default binding
var a = 'bar';// [call-site: global]
foo(); // 'bar' or undefined (strict mode)

It seems strange when you compare this behaviour with the OOP standards. This first rule isn’t that important because most JavaScript codes uses strict mode. Also, thank’s to ES6, developers will tend to use let and const instead of the legacy var.

当您将此行为与OOP标准进行比较时,这似乎很奇怪。 第一条规则并不重要,因为大多数JavaScript代码使用严格模式 。 另外,感谢ES6,开发人员将倾向于使用letconst代替传统的var

This is the first rule which is applied by default to bind a value to this. There are 4 rules in total. Here are the remaining 3 rules:

这是默认情况下将值绑定到this的第一条规则。 共有4条规则。 以下是剩余的3条规则:

// It’s not easy to understand, copy this code and do some tests!// #2: Implicit binding
const o2 = { a: 'o2', foo };
const o1 = { a: 'o1', o2 };o1.o2.foo(); // [call-site: o2] 'o2'// #3: Explicit binding
const o = { a: 'bar' };
foo.call(o); // [call-site: o] 'bar'const hardFoo = foo.bind(o); // [call-site: o]
hardFoo(); // [call-site: o] 'bar'// #4: New binding
function foo() {this.a = 'bar';
}
let result = new foo(); // [call-site: new]
console.log(result.a); // 'bar'

The last new binding rule is the first rule JavaScript tries to use. If this rule doesn’t apply, it’ll fall back to the other rules: explicit binding, implicit binding and eventually default binding.

最后一个新的绑定规则是JavaScript尝试使用的第一个规则。 如果该规则不适用,它将退回到其他规则: 显式绑定隐式绑定和最终默认绑定

The most important thing to remember:

要记住的最重要的事情:

this changes with the function call-site, rules for binding get priorities

这随函数调用站点而变化,绑定规则获得优先级

Besides those rules, there are still some edge-cases. It becomes a bit tricky when some rules are skipped depending on the call-site or this value.

除了这些规则,还有一些极端情况。 当根据呼叫站点或this值跳过某些规则时,这将变得有些棘手。

// 1- Call-site issue
const o = { a: 'bar', foo };
callback(o.foo); // undefinedfunction callback(func){func(); // [call-site: callback]
}// 2- Default binding isn't lexical binding
var a = 'foo';
function bar(func){var a = 'bar'; // Doesn't override global 'a' value for thisfunc();
}
bar(foo); // 'foo'// 3- this is null or undefined
var a = 'foo';
foo.call(null); // 'foo' because given 'this' is null

That’s it about this binding. I agree it’s not easy to understand at first glance but after a while it’ll sink in. You must put the effort in to learn how it works and practice a lot.

关于this绑定就是this 。 我同意乍一看并不容易,但是一会儿它就会陷入。您必须努力学习它的工作原理并进行大量练习。

To be honest, it’s a sum up from the entire third book of the series. Don’t hesitate to begin with this book and read some chapters. Kyle Simpson gives far more examples and very detailed explanations.

老实说,这是该系列第三本书的总结。 不要犹豫,从这本书开始阅读一些章节。 凯尔·辛普森( Kyle Simpson)提供了更多示例和非常详细的说明。

第七课:承诺模式 (LESSON 7— Promises pattern)

Before ES6, the common way to handle asynchronous programming was using callbacks. You call a function which can’t provide a result immediately, so you provide a function it’ll call once it finishes.

在ES6之前,处理异步编程的常用方法是使用回调。 您调用了一个无法立即提供结果的函数,因此您提供了一个一旦完成将立即调用的函数。

Promises are related to callbacks, but they’re going to replace callbacks. The concept of promises isn’t easy to grasp, so take your time to understand the example and try them!

承诺与回调相关,但是它们将替换回调。 许诺的概念并不容易掌握,因此请花一些时间来理解示例并尝试一下!

从回调到承诺 (From callbacks to promises)

First, let’s talk about callbacks. Did you realize that using them introduces an inversion of control (IoC) into the program execution? The function you’re calling gets the control over your script execution.

首先,让我们谈谈回调。 您是否意识到使用它们会在程序执行中引入控制反转 (IoC)? 您正在调用的函数可以控制脚本的执行。

// Please call 'eatPizza' once you've finished your work
orderPizza(eatPizza);function orderPizza(callback) {// You don't know what's going on here!callback(); // <- Hope it's this
}function eatPizza() {console.log('Miam');
}

You’ll eat your pizza, once it’s delivered and the order completed. The process behind orderPizza isn’t visible to us, but it’s the same for library’s functions. It may call eatPizza multiple times, none at all or even wait for a long time.

披萨送达并完成订单后,您将立即吃掉它。 对我们来说, orderPizza背后的过程是不可见的,但是对于库函数而言,过程是相同的。 它可能多次调用eatPizza ,根本没有调用,甚至等待了很长时间。

With promises, you can reverse the callbacks’ IoC. The function won’t ask for a callback but instead, give you a promise. Then, you can subscribe so you’ll get notice after the promise resolves (either with fulfillment or rejection).

使用promise,您可以撤消回调的IoC。 该函数不会要求回调,而是给您一个承诺。 然后,您可以订阅,以便在诺言解决(履行或拒绝)后得到通知。

let promise = orderPizza(); // <- No callback // Subscribes to the promise
promise.then(eatPizza);     // Fulfilled promise
promise.catch(stillHungry); // Rejected promisefunction orderPizza() {return Promise.resolve(); // <- returns the promise
}

Callback-based functions often ask for two callbacks (success and failure) or pass a parameter to the only callback and let you look for errors.

基于回调的函数通常要求两个回调(成功和失败),或者将参数传递给唯一的回调,然后让您查找错误。

With promises, those two callbacks change into then and catch. It matches success and failure but promise terms are different. A fulfilled promise is a success (with then) and a rejected promise is a failure (with catch).

有了promise,这两个回调就变成了thencatch 。 它匹配成功和失败,但是承诺条款不同。 一个履行承诺是成功的 (有then )和拒绝承诺是失败的 (有catch )。

Depending on the API, or the library you use for promises, the catch may not be available. Instead, then takes two functions as arguments, and it’s the same pattern as for callback-based functions.

根据API或用于承诺的库, catch可能不可用。 相反, then将两个函数用作参数,并且其模式与基于回调的函数相同。

In the example, orderPizza returns a fulfilled promise. Usually, this kind of asynchronous function returns a pending promise (documentation). But, in most cases, you won’t need the promise constructor because Promise.resolve and Promise.reject are enough.

在示例中, orderPizza返回已兑现的承诺。 通常,这种异步函数返回一个未决的Promise( 文档 )。 但是,在大多数情况下,您不需要Promise.resolve构造函数,因为Promise.resolvePromise.reject就足够了。

A promise is nothing more than an object with a state property. The function you’re calling changes this state from pending to fulfilled or rejected once it completes its work.

一个承诺只不过是一个带有状态属性的对象。 完成工作后,您正在调用的功能会将状态从挂起更改为完成拒绝

// Function executed even if there are no then or catch
let promise = Promise.resolve('Pizza');// Add callbacks later, called depending on the promise status
promise.then(youEatOneSlice);
promise.then(yourFriendEatOneSlice);
promise.then(result => console.log(result)); // 'Pizza'// Promise is an object (with at least a then function: it's a thenable object)
console.log(promise); // { state: 'fulfilled', value: 'Pizza' }

You can join a value to a promise. It’s forwarded to the subscribed callbacks as a parameter (then and catch). In this example, there are two subscriptions on the fulfillment callback. Once the promise fulfills, the two subscribed functions trigger in any order.

您可以将价值加入承诺。 它作为参数转发给订阅的回调( then catch )。 在此示例中,在实现回调上有两个预订。 一旦兑现承诺,两个订阅的功能将以任何顺序触发。

To sum up: there are still callbacks with promises.

综上所述:仍然存在带有承诺的回调。

But promises act like a trusted third party. They’re immutable after completion and so can’t resolve multiple times. Also, in the next part, you’ll see that it’s possible to react when a promise is still pending for a long time.

但是诺言的行为就像是可信赖的第三方。 它们在完成后是不变的 ,因此无法多次解析。 此外,在下一部分中,您将看到很长时间仍未完成承诺时,可能会做出React。

Note you can turn a callback-based function into a promise-based function with a few lines of code (see this gist). For sure there are libraries. Sometimes it’s also included in the language API (TypeScript has a promisify function).

请注意,您可以使用几行代码将基于回调的函数转换为基于promise的函数( 请参见本要点 )。 当然有图书馆。 有时,它也包含在语言API中(TypeScript具有Promisify函数)。

利用Promise API (Leverage the Promise API)

Both callback and promises have to deal with the issue of dependent asynchronous tasks. It occurs when the result of a first async function is necessary to call a second async function. Also, the third async function needs the result from the second function, and so on…

回调和Promise都必须处理相关的异步任务问题。 当需要第一个异步函数的结果来调用第二个异步函数时,就会发生这种情况。 另外,第三个异步函数需要第二个函数的结果,依此类推……

It’s important to look at how to handle this situation properly. That’s what leads to a horrible codebase. Look a the following code, you should be familiar with it:

重要的是要看看如何正确处理这种情况。 这就是导致可怕的代码库的原因。 看下面的代码,您应该熟悉它:

You’ve just meet a callback hell. To eat a pizza, the chef must cook it, then pack it and the delivery guy deliver it to you. Finally, you can eat the delivered pizza.

您刚刚遇到了一个回调地狱 。 要吃披萨,厨师必须将其煮熟,然后打包,送货员将其交付给您。 最后,您可以吃送来的披萨。

Each step is asynchronous and needs the previous step’s result. That’s the point which leads you to write callback hell code. Promises can avoid it because they can either return other promises or values (wrapped in a promise).

每个步骤都是异步的,需要上一步的结果。 这就是导致您编写回调地狱代码的关键。 承诺可以避免它,因为它们可以返回其他承诺或值(包装在承诺中)。

This snippet looks complex and simple at the same time. The code is small but it seems like we put in some magic things. Let’s split each step and get rid of ES6 syntax to make it clear:

该代码片段看起来既复杂又简单。 代码虽然很小,但是似乎我们做了一些神奇的事情。 让我们分开每一步,并摆脱一下ES6语法,以使其更加清晰:

// Detailled promise chain with plain ES5, try the pratice part!const cookPromise = cookPizza();const packPromise = cookPromise.then(function(pizza) {return pack(pizza); // Returns a promise stored in packPromise
});const deliverPromise = packPromise.then(function (packedPizza) { // value from pack(pizza)return deliver(packedPizza);
});deliverPromise.then(function (deliveredPizza) {return eat(deliveredPizza);
});/* For you to practice */
// - An example for cookPizza, pack, deliver and eat implementation
//   Each function append something to the previous step string
function pack(pizza) { return Promise.resolve(pizza + ' pack');
}// - Retrieve the result of eat and display the final string
//   Should be something like: 'pizza pack deliver eat'
eatPromise.eat((result) => console.log(result));

Now, you have the short syntax and the most verbose. To better understand this piece of code, you should:

现在,您的语法简短而冗长。 为了更好地理解这段代码,您应该:

  • Implement cookPizza, pack, deliver and eat functions

    实现cookPizzapackdelivereat功能

  • Check that each function changed the string using the eatPromise

    检查每个函数是否使用eatPromise更改了字符串

  • Refactor the code step by step to get to the short syntax逐步重构代码以获得简短的语法

There’s also the regular usage from promises. The Promises API also provides helpers to handle common concurrency interaction conditions such as gate, race and latch.

诺言中也有常规用法。 Promises API还提供了帮助程序来处理常见的并发交互条件,例如竞争闩锁

In this example, only the then is used but catch is also available. For Promise.all it’ll trigger instead of then if at least one promise is rejected.

在此示例中,仅使用了then ,但是catch也可用。 对于Promise.all它就会产生,而不是then如果至少一个诺言被拒绝。

As explained before, you can use promises to “check and act when a promise is still pending for a long time”. It’s the common use case for Promise.race. If you want to get a complete example with a timeout, check out this part of the book.

如前所述,您可以使用Promise“ 在Promise仍长时间未决时检查并采取行动 ”。 这是Promise.race的常见用例。 如果您想获取带有超时的完整示例,请查看本书的这一部分 。

借助ES7进一步发展 (Going further with ES7)

In some code, you might find deferred objects to handle promises. For instance, AngularJS provides it through the $q service.

在某些代码中,您可能会发现延迟的对象来处理Promise。 例如,AngularJS通过$ q服务提供它。

Using them seems more natural and understandable but they’re not. You better take your time to learn promises.

使用它们似乎更自然,更容易理解,但事实并非如此。 您最好花时间学习诺言。

You may need to return a promise and change its state later. Before you choose this solution, make sure there are no others ways. Anyway, the Promise API doesn’t return deferred objects.

您可能需要返回一个诺言,以后再更改其状态。 选择此解决方案之前,请确保没有其他方法。 无论如何,Promise API不会返回延迟的对象。

Don’t use a deferred object. If you think you need to, go over promises again

不要使用延迟的对象。 如果您认为需要,请再次履行承诺

But you can use the Promise constructor to mimic this behaviour. Check this gist of mine to know more but remember — it’s bad!

但是您可以使用Promise构造函数来模仿此行为。 查看我的要旨,以了解更多信息,但请记住,这很糟糕!

Last but not least, ES7 introduced a new way to handle promises by leverage generators syntax. It allows you to make asynchronous functions look like regular synchronous functions.

最后但并非最不重要的一点是,ES7引入了一种通过杠杆生成器语法处理承诺的新方法。 它使您可以使异步函数看起来像常规同步函数。

// ES6 syntax
function load() { return Promise.all([foo(), bar()]).then(console.log);
}
load();// ES7 syntax
async function load() { let a = await foo();// Gets here once 'foo' is resolved and then call 'bar'let b = await bar(); console.log(a, b);
}
load();

Flag the load which calls the asynchronous functions foo and bar with the async keyword. And put await before the asynchronous calls. You’ll be able to use the load as before, with a classic load().

使用async关键字标记调用异步函数foobarload 。 并在异步调用之前await 。 您将可以通过经典的load()像以前一样使用load

This syntax is appealing, isn’t it? No more callback and promise hell with infinite indentation. But wait, you should consider how generators work to avoid performances issues.

这种语法很吸引人,不是吗? 没有更多的回调,并承诺无限缩进。 但是,等等,您应该考虑生成器如何工作以避免性能问题。

In the above example, bar is only executed once foo promise resolves. Their execution isn’t parallelised. You’ll get the exact same result by writing something like foo.then(bar).

在上面的示例中,仅在foo promise解析后才执行bar 。 他们的执行不是并行的。 通过编写类似foo.then(bar)您将获得完全相同的结果。

Here is how to fix it:

解决方法如下:

async function load() {let fooPromise = foo();let barPromise = bar();// foo and bar are executed before Promise.alllet results = await Promise.all([fooPromise, barPromise]);console.log(results);
}
load();

Make use of the Promise.all. Actually, await means you want to execute your function step by step. First, from the beginning to the first await. Once the promise from the first await resolves, it’ll resume the function up to the next await keyword. Or to the end of the function if there aren’t more.

利用Promise.all 。 实际上, await意味着您要逐步执行功能。 首先,从开始到第一次await 。 第一次await的承诺解决后,它将恢复该函数,直到下一个await关键字。 如果没有更多内容,则到函数末尾。

In this example, foo and bar execute during the first step. The load function takes a break on Promise.all. At this point foo and bar already began their work.

在此示例中, foobar在第一步期间执行。 load函数在Promise.allPromise.all 。 此时foobar已经开始工作。

This was a quick introduction to promises with some notes about the traps you don’t want to fall into. This sums up of the fifth book of the series which describes in depth asynchronous patterns and promises.

这是对Promise的快速介绍,其中有一些关于您不希望陷入的陷阱的注释。 总结了本系列的第五本书,该书深入描述了异步模式和承诺。

You can also look at this article by Ronald Chen. He gathers a lot of promise anti-patterns. This article will help you to escape the so-called promise hell.

您也可以查看Ronald Chen的 这篇文章 。 他收集了很多有希望的反模式。 本文将帮助您摆脱所谓的诺言地狱。

结语 (Wrapping up)

These were the most important lessons I learned by reading You Don’t Know JS. This book series has way more lessons and details to teach you about how JavaScript works.

这是我通过阅读《不懂JS》中学到的最重要的课程。 这本书系列有更多的课程和细节,可以教您JavaScript的工作原理。

Just a heads up: for me, it was sometimes hard to follow when the author quotes the ECMAScript spec and lengthy examples. The books are long for sure, but also very complete. By the way, I almost give up but finally, I keep reading to the end and I can tell you — it was worth it.

请注意:对我而言,当作者引用ECMAScript规范和冗长的示例时,有时很难遵循。 这些书肯定很长,但也很完整。 顺便说一句,我几乎放弃了,但是最后,我一直读到最后,我可以告诉你-值得。

This isn’t some kind of advertising for Kyle. I just like this series and consider it a reference. Also, it’s free to read and contribute to the series through the GitHub repository.

这不是凯尔(Kyle)的广告。 我喜欢这个系列,并认为它是参考。 另外,可以通过GitHub存储库免费阅读和贡献该系列文章。

If you found this article useful, please click on the

您可能不了解JS:JavaScript圣经的见解相关推荐

  1. 阿提拉公司 java_Atitit  文件上传  架构设计 实现机制 解决方案  实践java php c#.net js javascript  c++ python...

    Atitit 文件上传 架构设计 实现机制 解决方案 实践 java php c#.net js javascript c++ python 1 . 上传的几点要求 2 1 .1. 本地预览 2 1 ...

  2. atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97

    atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97 1. 实现html5化界面的要解决的策略1 1.1. Js交互1 1.2. 动态参 ...

  3. java swing调用H5_atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97...

    atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97 1.实现html5化界面的要解决的策略 1.1.Js交互 Firefox与Chro ...

  4. [js]JavaScript Number.toPrecision() 函数详解

    [js]JavaScript Number.toPrecision() 函数详解 JavaScript: numberObject.toPrecision( [ precision ] ) 如果没有提 ...

  5. Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle...

    Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle 1. 主键1 2. uniq  index2 3.  ...

  6. java 返回js,Javascript返回上一页

    1. Javascript 返回上一页 history.go(-1), 返回两个页面: history.go(-2); 2. history.back(). 3. window.history.for ...

  7. Eclipse去除js(JavaScript)验证错误

    这篇文章主要是对Eclipse去除js(JavaScript)验证错误进行了介绍.在Eclipse中,js文件常常会报错.可以通过如下几个步骤解决 第一步: 去除eclipse的JS验证: 将wind ...

  8. 常用js(javascript)函数

    常用js(javascript)函数 1.常规函数 javascript常规函数包括以下9个函数: (1)alert函数:显示一个警告对话框,包括一个OK按钮. (2)confirm函数:显示一个确认 ...

  9. 模仿微信朋友圈 图片浏览 js javascript 支持图片预览,滑动切换,双指缩放,图片缓存

    模仿微信朋友圈 图片浏览 js javascript 支持图片预览,滑动切换,双指缩放,图片缓存 2017年08月10日 12:11:38 阅读数:2311 previewImage-mobile 仿 ...

  10. 原生JS javascript解除绑定事件 JS删除绑定事件

    原生JS javascript解除绑定事件 JS删除绑定事件 一.直接删除法 1.适用于直接绑定的事件,如: <h1 id="h1" onclick="_click ...

最新文章

  1. 收藏 | 2018年AI三大顶会中国学术成果全链接(附视频、PPT、论文)
  2. Nginx学习之HTTP/2.0配置
  3. IT人员健康信号之鼻炎养护
  4. C++ 容器适配器priority_queue的使用及实现
  5. 路由器的修改权限密码、还原出厂设置、备份配置文件和升级操作系统实际操作...
  6. postMessage可太有用了
  7. 如何在HTMl网页中插入百度地图
  8. centos下mysql备份数据库命令_[CentOS]下mysql数据库常用命令总结
  9. 串口屏和并口屏的区别?
  10. 测试用例管理工具有哪些?
  11. 计算机新生导学课心得,新生导学课论文_新生导学课感想_大一新生导学课心得...
  12. 【Linux】SIGCHLD信号
  13. 力扣(674.160)补8.30
  14. 特征工程-什么是特征工程(Kaggle微课)
  15. 如何做好IT战略规划与IT咨询!
  16. 【STC8学习笔记】STC8A8K64S4A12 程序烧录及使一个LED闪烁
  17. [数据结构][Python]python实现散列表
  18. 电子助视仪 对比增强算法 二十种色彩模式(Electronic Video Magnifier, 20 color mode)
  19. AURIX TC397 SCU 之 Watchdog 看门狗
  20. 有色金属行业数字化之路探析

热门文章

  1. 增值税发票税控开票软件V2.0.48_ZS_20220429(220518)-3
  2. MathType7.0嵌入Office2019教程
  3. 商务周刊:手机新三国演义
  4. 树莓派 安装谷歌拼音输入法(树莓派官方版系统、基于Debian)
  5. cnpack 菜单顺序
  6. HTML——HTML基础语法
  7. ssm+爱尚购物 毕业设计-附源码211622
  8. CSF文件格式播放器
  9. 保定学院计算机编程,惠普HP打印机驱动程序安装失败怎么办hewlett-packard上的文件...
  10. 用友ERP实施流程(不是本人所写,只是个搬运工!)