Understanding Async/Await patterns in JavaScript

那年仲夏 提交于 2019-12-20 02:26:34

问题


I'm relatively new to JavaScript programming, and so callbacks have been giving me trouble. 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.

What I want to do: The user enters a URL, data is fetched from the URL, processed, and put into a database. 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)? 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.

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.


回答1:


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. 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 (e.g., blocking). But the asynchronous functions you call within foo won't block the thread within foo; instead, foo returns a promise behind the scenes that gets resolved eventually after all the async work is done. (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)?

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 means the function returns a promise. await means you're waiting (asynchronously) for a promise resolution.

E.g.:

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.



来源:https://stackoverflow.com/questions/42677043/understanding-async-await-patterns-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!