如何从非异步函数的Web调用异步函数

时间:2019-12-01 00:43:00

标签: javascript node.js asynchronous promise async-await

我正在一个中等大小的node.js应用程序中工作,该应用程序具有一系列调用其他同步函数等的同步函数。为简单起见,我们只能说这些函数在此之前均未返回Promises。

function a(){
  ...
  return c();
}
function b(){
  ...
  return c();
}
function c(){
  ...
  return e();
}
function d(){
  ...
  return e();
}
function e(){
   // Do stuff
}

实际上,它比这复杂得多,并且具有一整套调用这些功能的单元/集成测试。

我们现在需要使用e()函数来等待异步函数的结果:

function e(){
   const someData = await someAsyncFunction();
   const dataINeedNow = someData.dataINeedNow;
   // Do something with dataINeedNow
}

async function someAsyncFunction(){
  ...
  return await someExternalService();
}

似乎一般的智慧是,一旦您开始返回承诺,就应该继续返回承诺。在上面的示例中,这将涉及使a,b,c,d和e全部为async,但实际上,这将涉及应用程序中的〜100项更改。

有没有一种方法可以在没有主要重构的情况下在node.js应用程序的肠道中对await someExternalService();进行一次调用?

2 个答案:

答案 0 :(得分:1)

您可能应该重写整个链,以返回保证一致性的诺言,而不会使您的代码非常混乱。

但是,根据您编写问题的方式,如果您真的要返回每个后续调用的结果,则可以在嵌套外部处理promise结果。

add_action('rest_api_init', function () { register_rest_route( 'yith-composite', 'add-item',array( 'methods' => 'POST', 'callback' => 'yith_custom_add_item' )); }); function yith_custom_add_item( WP_REST_Request $request ) { $currentuserid_fromjwt = get_current_user_id(); $user = get_user_by( 'id', $currentuserid_fromjwt ); if( $user ) { wp_set_current_user( $user_id, $user->user_login ); wp_set_auth_cookie( $user_id ); do_action( 'wp_login', $user->user_login, $user ); $product_id = $_GET['id']; $url = get_permalink( $product_id ); $cookie = ''; foreach ($_COOKIE as $key => $value) { $cookie .= $key . '=' . $value . ';'; } $response = wp_remote_post( $url, array( 'headers' => array( 'Cookie' => $cookie, // 'Authorization' => $request->get_header('Authorization'), 'Content-Type' => 'application/x-www-form-urlencoded', ), 'body' => $_POST, )); if ( !empty($response) ) { return $response } } } 上返回一个诺言,该诺言将一直返回到您的原始通话

function e

使用来自

的回复写 function e(){ console.log("did e"); const prom = new Promise((resolve)=>{ setTimeout(()=>{ console.log("resolved async"); resolve("dataResolve") },1000) }); return prom; }
Do something with dataINeedNow

查看示例here

答案 1 :(得分:-1)

只需使用e()处理then/catch中的Promise。

您的e()如下:

function e(){
   someAsyncFunction()
   .then(data => {
      const dataINeedNow = data.dataINeedNow;
      // Do something with dataINeedNow;
    })
   .catch(e => {
        // Do something if someExternalService throws rejection
        console.log(e);
    })
}

function someAsyncFunction(){
  ...
  // This works provided someExternalService() returns a Promise.
  return someExternalService();
}

async / await只是用于Promise处理的语法糖。我不喜欢它,因为它为不想学习如何在JavaScript中正确处理并发性的开发人员提供了一种使其应用程序伪同步的方法。

如果您觉得这很陌生,建议您检查JavaScript中的并发模式。特别是回调和Promise链接。