Node.js:异步调用后执行代码的哪些部分?

时间:2017-04-18 10:52:48

标签: javascript node.js asynchronous

异步调用是javascript的固有部分,使用回调通常是处理这些调用的优雅工具。

但是,我不太确定异步操作后代码的分支是如何决定的。例如,以下代码会发生什么?

function f(callback) {
   value = some_async_call();
   if (value) {
       callback(value);
   }
   return(value);
}

这会发生什么?根据我的简短JS经验,return会发回undefined值。但是假设value从异步调用返回true,是否会使用正确的值或undefined值调用回调?

换句话说,是否存在关于在异步调用之后立即执行哪些操作以及哪些操作被延迟直到返回值的规则?

在询问

之前我尝试了什么

SFTW用于在javascript中分支异步调用,但没有发现任何规范或决定性的内容。

2 个答案:

答案 0 :(得分:3)

你是对的,undefined将被退回。在异步操作之后执行逻辑,应该将回调传递给该函数。您正在尝试以同步方式使用代码,async/await可以解决问题。假设您可以写some_async_call returns Promise

async function f(callback) {
  var value = await some_async_call();
  if (value) {
    callback(value);
  }
  return value;
}

在这种情况下,您的函数将返回值Promise并且也将是异步的。阅读更多here

甚至更多你不需要传递回调。您可以在客户端代码中await使用您的函数并从那里执行回调。

关于分支,您可以在不使用async/await的情况下进行分支的唯一方法是让some_async_call接受一个接受value作为参数的回调:

function f(callback) {
 some_async_call(function(value) {
   if (value) {
     callback(value);
   }
 });
}

再次重申,除了Promise之外,无法从异步方法返回值。或RxJS中的Observable

答案 1 :(得分:3)

更新:在底部的3种不同方法之间添加了实际差异

我们假设98被定义为异步函数:blabla = []

此函数返回的是blabla.append('string stuf') ,这意味着blabla += ['string stuf'] 现在是一个承诺:blabla.extend(['string stuf'])

当我将其翻译成代码时:

some_async_call();

我现在可以做两件事:

async function some_async_call() { ... }

或:

Promise

然而,这也将父函数转换为异步函数,这意味着该函数的立即返回值也是一个承诺。

长话短说:

您可以使用回调来流经异步函数或promises,或async / await

<强>回调

value

<强>许

value.then( function(result) { } )

<强>异步/ AWAIT

async function some_async_call() { 
    if (theMoonIsInTheRightPosition)
        return Fetch('/api/data/') // this returns a promise as well.

    return false;
}

你可以看到:promises和async / await使用相同的机制,真的值得一读。

三者之间差异的实际例子:

<强>回调

function parentFunction(callback) {
    var promise = some_async_call();
    promise.then( callback );
    return ...; // you can't "return" the value of an async call synchronously, since it is a promise.
}

<强>许

async function asyncParentFunction( callback ) {
    var value = await some_async_call();
    if (value)
        callback( value );
    return value;
}

<强>异步/ AWAIT

function doStuff(callback) {
    // do asynchronous stuff
    var result = 100;
    callback(result); // once you're done with stuff
}
doStuff( function(data) { console.log('Im done!', data); } );