简体   繁体   English

了解JavaScript中的异步/等待模式

[英]Understanding Async/Await patterns in JavaScript

I'm relatively new to JavaScript programming, and so callbacks have been giving me trouble. 我对JavaScript编程比较陌生,所以回调一直给我带来麻烦。 I'm using a framework that supports the "async/await" syntax from ES7 (Meteor), but I'm having some difficulty understanding exactly how I can implement an asynchronous function that calls other functions. 我正在使用支持ES7(Meteor)的“async / await”语法的框架,但是我很难理解如何实现调用其他函数的异步函数。

What I want to do: The user enters a URL, data is fetched from the URL, processed, and put into a database. 我想做的事:用户输入URL,从URL获取数据,处理数据并将其放入数据库。 I want this to occur in a non-blocking manner, so that the user can continue to use the application while this process is occurring. 我希望以非阻塞方式进行此操作,以便用户可以在此过程发生时继续使用该应用程序。

Pseudocode: 伪代码:

async function foo(URL) {
    try {
        //using request-promise npm package to make the request
        const data = await makeRequestPromise(URL) 
        const parsedData = await myParsingFunciton(data);
        MyDB.insert({
            parsedData,
        });
    catch (err) {
        console.log(err);
    }

So I have a few questions: 所以我有几个问题:

  • Is anything that happens in the scope of this async function non-blocking? 在这个异步函数范围内发生的任何事情都是非阻塞的吗?
  • If so, can I just use a series of synchornous functions since I can't parse the data before I receive it anyway? 如果是这样,我可以使用一系列同步函数,因为我无论如何都无法解析数据吗?
  • What happens if I try to await a function that is not defined as asynchronous (for example myParsingFunction)? 如果我尝试等待未定义为异步的函数(例如myParsingFunction)会发生什么? My research seems to imply that the function is forced to return a promise, but I'm not certain how I would determine that. 我的研究似乎暗示该函数被迫返回一个承诺,但我不确定我将如何确定。 Doing so in the code does not return an error, but JavaScript seems surprisingly tolerant of weirdness with regards to returns. 在代码中这样做不会返回错误,但JavaScript似乎出乎意料地容忍返回方面的怪异。

I would like to add that my function works and things go into the database, but I have no idea how to test if it is actually non-blocking. 我想补充一点,我的函数可以工作,而且事情会进入数据库,但我不知道如何测试它是否实际上是非阻塞的。

Is anything that happens in the scope of this async function non-blocking? 在这个异步函数范围内发生的任何事情都是非阻塞的吗?

It's non-blocking in the sense that the call to foo won't stall the thread until all the work is done, because foo is an asynchronous function calling at least one other asynchronous function. 这是无阻塞的,即调用foo不会拖延线程,直到所有的工作都做了,因为foo是一个异步函数调用至少一个其他异步功能。 There's only one main UI thread on browsers (and one thread in NodeJS), so unless you use web workers in the browser, the asynchronous code will at some point be occupying that thread (eg, blocking). 浏览器上只有一个主要UI线程(NodeJS中有一个线程),因此除非您在浏览器中使用Web worker,否则异步代码将在某个时刻占用该线程(例如,阻塞)。 But the asynchronous functions you call within foo won't block the thread within foo ; 但是你在foo调用的异步函数不会阻塞foo的线程; instead, foo returns a promise behind the scenes that gets resolved eventually after all the async work is done. 相反, foo会在所有异步工作完成后返回最终解决的幕后承诺。 (That's why it's an asynchronous function.) (这就是为什么它是异步功能。)

If so, can I just use a series of synchornous functions since I can't parse the data before I receive it anyway? 如果是这样,我可以使用一系列同步函数,因为我无论如何都无法解析数据吗?

Not quite following this question. 不太关注这个问题。 Your code looks fine. 你的代码看起来很好。 It looks synchronous, but it isn't, assuming one or more of the functions you're calling is asynchronous. 它看起来是同步的,但它不是,假设你调用的一个或多个函数是异步的。

What happens if I try to await a function that is not defined as asynchronous (for example myParsingFunction)? 如果我尝试等待未定义为异步的函数(例如myParsingFunction)会发生什么?

It makes your call to that function asynchronous (even though the function isn't) but then the resolution happens as soon as possible thereafter; 它使您对该函数的调用异步(即使该函数不是),但此后解析会尽快发生; the resolution value is the value returned by the function. 分辨率值是函数返回的值。 You can see that in action with this quick experiment: 你可以看到这个快速实验的实际应用:

 // `foo` is an asynchronous function, and so calling it returns a promise async function foo() { // We haven't awaited anything yet, so this is run synchronously when we // call `foo` console.log("A"); // `Math.random` is, of course, a synchronous function; but we *call* it // asynchronously since we've used `await` let data = await Math.random(); // Which means this line doesn't run until later, after `foo` has already // returned its promise console.log("B"); } // When we call `foo`, the synchronous part runs first and it returns its // promise (which we're not using) foo(); // And then this line runs, BEFORE the asynchronous part of `foo` can run console.log("C"); // ...and so we see A, C, B; without the `await` on the call to // `Math.random`, we'd see A, B, C 


It may (or may not!) be useful to remember that async / await is purely syntactic sugar for interacting with promises. 它可能(或可能不是)有用来记住async / await是纯粹的语法糖,用于与promises交互。 async means the function returns a promise. async表示函数返回一个promise。 await means you're waiting (asynchronously) for a promise resolution. await意味着您正在等待(异步)进行承诺解析。

Eg: 例如:

async function foo() {
    return 42;
}

is sugar for 是糖

function foo() {
    return new Promise(resolve => {
        resolve(42);
    });
}

and sugar for 和糖

let data = await something();
// ...do somthing...

is

something().then(data => {
    // ...do something...
});

leaving aside some minor details. 抛开一些细节。

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

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