了解JavaScript

时间:2017-03-08 16:43:50

标签: javascript async-await

我对JavaScript编程比较陌生,所以回调一直给我带来麻烦。我正在使用支持ES7(Meteor)的“async / await”语法的框架,但是我很难理解如何实现调用其他函数的异步函数。

  

我想做什么:用户输入URL,从URL获取数据,处理数据并将其放入数据库。我希望以非阻塞方式进行此操作,以便用户可以在此过程发生时继续使用该应用程序。

伪代码:

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);
    }

所以我有几个问题:

  • 此异步函数范围内发生的任何事情都是非阻塞的吗?
  • 如果是这样,我可以使用一系列同步函数,因为我无论如何都无法解析数据吗?
  • 如果我尝试等待未定义为异步的函数(例如myParsingFunction)会发生什么?我的研究似乎暗示该函数被迫返回一个承诺,但我不确定我将如何确定。在代码中执行此操作不会返回错误,但JavaScript似乎出乎意料地容忍返回方面的怪异。

我想补充说我的函数正常工作并且事情会进入数据库,但我不知道如何测试它是否实际上是非阻塞的。

1 个答案:

答案 0 :(得分:8)

  

此异步函数范围内发生的任何事情都是非阻塞的吗?

它是非阻塞的,因为foo的调用不会使所有工作都停止,因为foo是一个调用的异步函数至少一个其他异步函数。浏览器上只有一个主UI线程(NodeJS中有一个线程),因此除非您在浏览器中使用Web worker,否则异步代码将在某个时刻占用该线程(例如,阻塞)。但是你在foo内调用的异步函数不会阻塞foo中的线程;相反,foo返回幕后的一个承诺,在完成所有异步工作后最终得到解决。 (这就是异步功能的原因。)

  

如果是这样,我可以使用一系列同步函数,因为无论如何我都无法解析数据吗?

不太关注这个问题。你的代码看起来很好。它看起来是同步的,但它不是,假设您调用的一个或多个函数是异步的。

  

如果我尝试等待未定义为异步的函数(例如myParsingFunction)会发生什么?

它会使您对该函数的调用异步(即使该函数不是),但此后分辨率会尽快发生;分辨率值是函数返回的值。你可以通过这个快速实验看到这一点:



// `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




它可能(或可能不是)有用来记住async / await纯粹是用于与承诺交互的语法糖。 async表示函数返回一个promise。 await表示您正在等待(异步)进行承诺解析。

E.g:

async function foo() {
    return 42;
}

是糖的

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

和糖

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

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

暂时搁置一些细节。