【问题标题】:C# async Task vs Js async Task (node js)C# 异步任务与 Js 异步任务(节点 js)
【发布时间】:2020-09-19 22:15:23
【问题描述】:

好的,所以我知道如何用 C# 编程,而且我最近开始用 JS 编程(node js)。老实说,我对异步调用感到震惊。

假设我在 C# 中有这段代码:

var t_1 = SomeAsyncTask();
var t_2 = SomeOtherAsyncTask();
Task.WaitAll(t_1, t_2);
var res_1 = t_1.Result;
var res_2 = t_2.Result;

有 JS 等价物吗?到目前为止,我已经做到了:

In User.js:
var express = require("express");
var router = express.Router();
var sqlDo = require("../../js_help/DatabasReq/sqlDo.js");
router.get("/", async function(req, res){
    var json = sqlDo.ExecCommand("select * from Users");
    res.send(json); //json.recordset
});
module.exports = router;

In sqlDo.js:
module.exports = {
    ExecCommand: function(command){
        // sql and config are defined before.
        sql.connect(config, function () {
            var request = new sql.Request();
            request.query(command, function (err, recordset) {
                if (err) console.log(err)
                console.log(recordset.recordset);
                return recordset;
            });
        });
    }
};

我的问题是这段代码是异步运行的。我曾尝试将 await 放到不同的地方,但没有任何效果。所以当我启动我的服务器时,它什么也不返回。我可以说它正在完成一个调用,因为我让它将结果读入控制台。

感谢您的帮助!

顺便说一句:我试过谷歌搜索/stackoverlow-ing,.. 但我找不到任何看起来像 C# 等效的东西。甚至可以像在c#中那样编写它吗?再次感谢您的每一个回答...

【问题讨论】:

  • 最接近Task.WaitAll(t1, t2) 的是Promise.all([p1, p2]),因为JS 中的async/await 或多或少是promise 的语法糖。
  • 毫不夸张地说,所有“经典”语言(C、C++、Java 和 C#)本质上都是“阻塞”的,而且,相反,Javascript总是“异步”。在 JS 中实现“等待”的一种方法是使用 Promises。 “异步”被固定在更高版本的 .Net/C# 中;对更高版本的 JS 的“承诺”。
  • 好的,那么我怎样才能加入数据库,然后返回来自数据库的数据的响应。而且我想在某些功能中使用它,以便我可以重复使用它?
  • 问:好的,那我怎样才能加入数据库...? A:看看我引用的链接。让你的回调返回一个承诺;让您的来电者等待承诺。简单的;)
  • 要留在上面的例子中:ExecCommand 必须是一个async 函数(即返回一个承诺),并且在你的请求处理程序中你必须在返回结果之前await ExecCommand(...)。基本相同,就像你在 C# 中使用 Tasks 所做的那样

标签: javascript c# node.js asynchronous async-await


【解决方案1】:

要使您的 ExecCommand 函数异步,您必须使其返回一个 Promise。阅读 Promises,例如 here

module.exports = {

  ExecCommand: function(command){
    return new Promise((resolve, reject) => {  //return a Promise from the function
      sql.connect(config, function () {
        var request = new sql.Request();
        request.query(command, function (err, recordset) {
          if (err) {
            reject(err);  //if there is an error, reject the Promise
          } else {
            resolve(recordset);  //if no error, resolve the Promise with the result
          }
        });
      });
    });
  }
};

根据您的 SQL 库,它也可能已经支持 Promise,而不是回调

module.exports = {

  ExecCommand: function(command) {
     return sql.connect(config)
       .then(() => {
          return new sql.Request().query(command);
       })
  }
};

async/await

module.exports = {

  ExecCommand: async function(command) {
    await sql.connect(config);
    return await new sql.Request().query(command);         
  }
};

然后你可以像这样在requesthandler中调用这个函数

router.get("/", async function(req, res){
  try {
    var json = await sqlDo.ExecCommand("select * from Users");
    res.send(json); 
  catch (err) {
    console.log(err);
    res.sendStatus(500);
  }
});

或者像这样

router.get("/", function(req, res){
  sqlDo.ExecCommand("select * from Users")
    .then(json => { //the promise resolved
      res.send(json);
    })
    .catch(err => { //the promise rejected
      res.sendStatus(500); 
      console.log(err); 
    });
});

我更喜欢第二种变体。但这可能只是我个人的看法......

【讨论】:

  • 哇!谢谢,我实际上从您的示例中了解了正在发生的事情。批准并投票。希望你度过愉快的一天
猜你喜欢
  • 1970-01-01
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-06
  • 2018-07-03
  • 1970-01-01
  • 2017-09-30
  • 2016-11-23
相关资源
最近更新 更多