简体   繁体   English

澄清 javascript 中的承诺

[英]clarification about promises in javascript

I am confused with certain parts regarding promises, I have read multiple articles and I have seen multiple videos and I want to ask a few things:我对有关承诺的某些部分感到困惑,我阅读了多篇文章并且看过多个视频,我想问几件事:

from what I understand currently, when a promise is created is starts running.据我目前了解,创建 promise 后开始运行。

Do I need to await on the promise if the value that returned from the promise is not used in the code?如果代码中未使用从 promise 返回的值,我是否需要等待 promise?

a scenario for that is: let's say I am processing a task in my system and I want to log the information to mongodb, when I invoke the insert function I get a promise back.一个场景是:假设我正在我的系统中处理一个任务,我想将信息记录到 mongodb,当我调用插入 function 时,我得到一个 promise。 the execution beings but I don't care about the result of it处决存在但我不在乎它的结果

if I am not awaiting and there is an error I wouldn't be able to handle it.如果我不等待并且出现错误,我将无法处理它。

A followup question to the question above:上述问题的后续问题:

from what I read whenever I await it actually blocks the execution of the async function, but if it blocks the execution of the function how doesn't it block the rest of the eventloop?从我每次await时读到的内容来看,它实际上阻止了异步 function 的执行,但是如果它阻止了 function 的执行,它怎么不阻止事件循环的 rest?

Basic concepts基本概念

The whole point of the event loop is to have many microtasks that do not affect each other (hence by default there is no effect).事件循环的全部意义在于拥有许多互不影响的微任务(因此默认情况下没有影响)。

To chain microtasks first;首先链接微任务; there were callbacks, then Promises ( then / catch ) then the async / await API. The last two can be considered just syntactic sugar atop the callback concept.有回调,然后是 Promises( then是 / catch ),然后是async / await API。最后两个可以被认为只是回调概念之上的语法糖。 There are no 'functionalities' added but rather a different syntax to achieve the same stuff in simpler and more elegant ways (Pyhilosophicaly).没有添加“功能”,而是使用不同的语法以更简单和更优雅的方式实现相同的东西(Pyhilosophicaly)。

The event loop executes all the queued microtasks at each loop and repeats.事件循环在每个循环中执行所有排队的微任务并重复。 Unless you have blocking code (and await is not to be considered blocking) your event loop never stalls and hence other tasks are not affected.除非您有阻塞代码(并且await不被视为阻塞),否则您的事件循环永远不会停止,因此其他任务不会受到影响。

You are trying to understand await from the perspective of real blocking code as intended in other languages.您正在尝试从其他语言中预期的真正阻塞代码的角度来理解await

IMHO you first need to deeply understand how callbacks work, then study Promises (as a tool to make callbacks less messy) and then async / await (as a syntax to make Promises pretties).恕我直言,您首先需要深入了解回调的工作原理,然后研究 Promises(作为使回调不那么混乱的工具),然后是async / await (作为使 Promises 更漂亮的语法)。 But keep in mind, the underlying system is the same: functions that call functions that get handled functions to be eventually called in future).但请记住,底层系统是相同的:调用函数的函数,这些函数得到处理的函数,最终在将来被调用)。

Specific questions具体问题

When a promise is created is starts running创建 promise 后开始运行

Yes, but no.是的,但不是。 A promise does not run, a promise is only a contract you receive by a part of code that will be used to notify you of the outcome.一个 promise 没有运行,一个 promise 只是你通过一部分代码收到的合同,将用于通知你结果。 So the promise does not run, is the mean that has been created for you after you requested a task to be executed.所以 promise 不运行,是指在您请求要执行的任务后为您创建的。

So typically if a promise has been handled to you there is something 'running'.因此,通常如果 promise 已处理给您,则有一些“正在运行”。 But Promise may be used differently and there may be something 'waiting'.但是Promise可能会以不同的方式使用,并且可能有一些“等待”。

A promise is not linked to the execution of the task hence it can not start nor stop it. promise 未链接到任务的执行,因此它无法启动或停止它。

Do I need to await on the promise if I'm not interested in the outcome如果我对结果不感兴趣,是否需要等待 promise

No, you are not required to.不,您不需要这样做。 But keep in mind that not handling promise exceptions is being deprecated and may result in system failure.但请记住,不处理 promise 异常已被弃用,可能会导致系统故障。 You should always handle (or let bubble) exceptions.您应该始终处理(或冒泡)异常。

There would be a failure if there is an unhandled promise rejection.如果有未处理的 promise 拒绝,将会失败。 In synchronous code this is equivalent to an uncaught thrown error.在同步代码中,这相当于未捕获的抛出错误。 Until now(-ish) uncaught promise rejections were tolerated but there isn't a really good reason for that.直到现在(-ish)未捕获的 promise 拒绝被容忍,但没有一个很好的理由。 Node is moving to treat them the same as any other error that bubbles to the top. Node 正在努力将它们与冒泡到顶部的任何其他错误一样对待。

VLAZ VLAZ

You are considering promises only with async / await but the underlying Promise api is .then() and .catch() .您正在考虑仅使用async / await的承诺,但底层Promise api 是 .then .then().catch() Using this API you can use promises in a 'fire-and-forget' fashion:使用这个 API 你可以以“即发即弃”的方式使用承诺:

async function Do() {
  await before();
  asyncDbCall().catch(err => console.error(err))
  await after();
}

In this example you are not waiting for asyncDbCall() but still .catch(err => console.error(err)) will result in the error being logged (some time in the future, probably even after Do() has completed).在此示例中,您没有等待asyncDbCall() ,但.catch(err => console.error(err))仍然会导致错误被记录(在将来的某个时间,甚至可能在Do()完成之后)。

Or you can branch off the execution to other async executions, take this complex example:或者您可以将执行分支到其他异步执行,以这个复杂的例子为例:

async function Do() {
    await before();
    // This will execute AFTER before() & only if before() succeeded
    asyncDbCall()
        .then(async value => {
            // This will execute after `asyncDbCall()` and only if it succeeded
            await something(value);
            // We reach here after `something()` and only if succeeded
        })
        .catch(err => {
            // This will execute if `asyncDbCall()` fails of IF ANYTHING
            // within `async value => {}` fails
            console.error(err);
        })
    // This will execute AFTER before() and only if before() succeeded and
    // asyncDbCall() call (but not Promise) succeeded
    await after();
}

Await it actually blocks the execution of the async function等待它实际上阻止了异步 function 的执行

Await stops the async function (hence also anything that is awaiting for the function) but does not affect anyway the event loop. Await 停止async function(因此也停止等待函数的任何内容)但无论如何都不影响事件循环。

from what I understand currently, when a promise is created is starts running.据我目前了解,创建 promise 后开始运行。

It is not.它不是。 It has its internal state set to pending .它的内部 state 设置为pending Promise's constructor takes a callback as an argument, and in turn provides it with resolve and reject callbacks. Promise 的构造函数将回调作为参数,然后为其提供resolvereject回调。

What it also does is that it allows to provide a number of actions that happen when it's state changes to resolved or rejected .它还可以做的是,它允许提供一些在 state 更改为resolvedrejected时发生的操作。 Outside of async/await , you might know them as .then and .catch instance methods of Promise class. Once the state is changed, they will be executed.async/await之外,您可能知道它们是Promise class 的.then.catch实例方法。一旦 state 被更改,它们将被执行。

Do I need to await on the promise if the value that returned from the promise is not used in the code?如果代码中未使用从 promise 返回的值,我是否需要等待 promise?

No, that is entirely up to you.不,这完全取决于你。

a scenario for that is: let's say I am processing a task in my system and I want to log the information to mongodb, when I invoke the insert function I get a promise back.一个场景是:假设我正在我的系统中处理一个任务,我想将信息记录到 mongodb,当我调用插入 function 时,我得到一个 promise。 the execution beings but I don't care about the result of it处决存在但我不在乎它的结果

if I am not awaiting and there is an error I wouldn't be able to handle it.如果我不等待并且出现错误,我将无法处理它。

You can still use .catch to handle the error without awaiting for the Promise to finish您仍然可以使用.catch来处理错误,而无需等待Promise完成

A followup question to the question above:上述问题的后续问题:

from what I read whenever I await it actually blocks the execution of the async function, but if it blocks the execution of the function how doesn't it block the rest of the eventloop?从我每次等待时读到的内容来看,它实际上阻止了异步 function 的执行,但是如果它阻止了 function 的执行,它怎么不阻止事件循环的 rest?

Promises have nothing to do with the event loop. Promises 与事件循环无关。

You can read more about the EventLoop here.您可以在此处阅读有关 EventLoop 的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM