【问题标题】:How to do things synchronously in node如何在节点中同步做事
【发布时间】:2017-05-26 07:00:45
【问题描述】:

我知道节点是所有关于异步的东西,但我想在串行模式下做如下的事情:

发出 api 请求 > 将 body xml 转换为 JSON.stringify > 将字符串传递给模板。

request.get({url:url, oauth:oauth}, function(err, res, body){
    parseString(body, function(err, result){
        output = JSON.stringify(result);

        res.render('home', { title: 'Fantasy Home', 
                output: output });
    });
});

现在我想按顺序执行此操作,但是对于所有回调,我感到很困惑。

res.render 不能嵌套在回调中,因为 res 对象不存在。把它放在外面是行不通的,因为它会在回调执行之前运行,所以你会得到“未定义”的输出。

必须有一种按顺序做事的方法。为什么一切都是回调?为什么这些函数不能只返回一个常规的非回调结果?

我怎样才能做到这一点?

【问题讨论】:

  • 至于为什么:@tjameson 解释的很好here
  • res.render doesn't work nested inside callbacks because the res object doesn't exist 这是完全错误的。 res 对象存在。如果您有错误,那不是错误的原因
  • 您的代码已经可以按顺序运行了。访问res 可能不起作用,因为您使用request.get 回调的res 参数对其进行了隐藏。
  • 你明白@Bergi 的评论吗?这是解决您问题的关键

标签: javascript express


【解决方案1】:

其他人没有提及为什么您的res.render 不起作用。 你可能有这样的事情:

app.get('/', function(req, res, next) { // You need the res here to .render

    request.get({url:url, oauth:oauth}, function(err, res, body){ // But you are using this res instead, which does not have the render method
        parseString(body, function(err, result){
            output = JSON.stringify(result);

            res.render('home', { title: 'Fantasy Home', 
                    output: output });
        });
    });
});

阅读代码中的 cmets。所以您的解决方案是,使用请求处理程序中的res.render,将request.get 回调中的res 重命名为其他名称。

【讨论】:

    【解决方案2】:

    你应该使用中间件,promise 是在节点中使用异步的更好的方法,但我会向你展示回调。强烈建议不要用同步调用阻塞你的线程!由于 node.js 是单线程的。 next() 是这里的回调,因此中间件在调用 next() 之前不允许执行主路由函数(使用 res.render)。您可以传递任意数量的中间件。

    app.use('/user/:id', middleware, (req, res) => {
        //here you'll find your data
        console.log(req.callData);
        res.render(view, req.callData);
    }
    middleware(req, res, next) => {
        dotheCall(dataToPass, (err, cb) => {
            req.callData = cb;
            // remember about handling errors of course!
            return next();
        })
    }
    

    【讨论】:

      【解决方案3】:

      如果我们使用同步代码,JavaScript 是单线程的,那么这本身就是一个关于响应时间(node.js)和所有问题的大问题。由于事件循环的好处,一切都以回调方式实现。

      你可以深入了解一下事件循环:https://youtu.be/8aGhZQkoFbQ(很好的解释)

      您可以将 Promisification 用于您想要实现的场景:http://bluebirdjs.com/docs/getting-started.html

      request.get({url:url, oauth:oauth}, function(err, res, body) {
          // Note :: This is Promisified Function
          return parseString(body)
              .bind(this)
              .then(function(result) {
                  output = JSON.stringify(result);
      
                  res.render('home', {title: 'Fantasy Home', output: output });
      
                  return true;
              })
              .catch(function(error)
              {
                  // Error Handling Code Here
                  // Then send response to client
              });
      });

      您可以使用以下方法实现promisified功能

      function parseString(body) {
          var Promise = require("bluebird");
      
          return new Promise(function(resolve,reject) {
              // Your Parsing Logic here
      
              if(is_parsed_successfully) {
                  return resolve(parsed_data);
              }
      
              return reject(proper_err_data);
          })
      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-14
        • 1970-01-01
        • 1970-01-01
        • 2020-07-16
        • 1970-01-01
        • 2017-11-22
        相关资源
        最近更新 更多