【问题标题】:How to pass a result from one then() block to the next then() block in a JavaScript Promise?如何将结果从一个 then() 块传递到 JavaScript Promise 中的下一个 then() 块?
【发布时间】:2020-02-23 18:22:50
【问题描述】:

我想从一个 GET 请求中进行 2 个 MySQL 查询,将结果组合在一起并返回它们。但是我很难将第一个查询的结果传递给下一个 then() 块。

const express = require('express');
const router = express.Router();
const axios = require('axios');
const con = require('../../db');

router.get('/:id', (req, res, next) => {
axios.get('/').then(docs => { //get one book by its id number
    const sql = "SELECT title, line, mage_edition FROM books WHERE id=" + req.params.id;
    con.query(sql, (err, result) => {
        if (err) {
            throw err;
        }
        return result; //"result" shows proper value here
    });
}).then(docs => { //get all the listings that appear inside that book
    //How do I get "result" here?
    const sql2 = "SELECT l.entry_id, e.title, e.kind, e.sort FROM links l INNER JOIN entries e ON l.entry_id = e.id WHERE book_id=" + req.params.id;
    con.query(sql2, (err, result2) => {
        if (err) {
            throw err;
        }
        //combine result and result2, then give back with res.status(200).json()
    })
});
});
module.exports = router;

任何帮助将不胜感激。我完成了一个关于异步 JavaScript 的培训视频系列,但我无法弄清楚这一点。

【问题讨论】:

  • 我知道你的问题是关于链式承诺的,但在这种情况下,没有必要,你只需一条 SQL 语句就可以从数据库中获取所有信息。
  • trincot,在大多数情况下,这将是一个很好的建议。在我的情况下,这 2 个查询结果是如此不同,它需要更多的时间来“规范化”列以组合查询和额外的工作来理解结果。

标签: javascript node.js promise axios


【解决方案1】:

要从一个.then 返回到下一个.then,您应该从previous 返回值。您的代码不起作用,因为您正在从回调函数返回结果。回调函数不能返回值。

检查您的.query 函数是否返回任何承诺。如果是,那么您应该这样做const result = awati con.query(sql);

或者,您可以承诺您的 .query 函数,然后等待它。

【讨论】:

    【解决方案2】:

    使用return 关键字在then() 块内返回结果。这应该 m 是下一个块可用的数据。

    请记住,如果您需要按顺序执行 then 块,则需要返回 Promise 而不是解析值

    【讨论】:

      【解决方案3】:

      问题是您的查询调用没有返回承诺,它只是在完成时调用回调。如果您使用的任何数据库库不支持返回 Promise,我建议为您的查询方法创建包装函数,以返回 Promise。这将使将它们链接到 Promise 中变得更加容易。

      类似这样的:

      function queryPromise(con, sql) {
          return new Promise((resolve, reject) => {
            con.query(sql, (err, result) => {
              if (err) { return reject(err); }
              return resolve(result);
            });
          });
      }
      

      【讨论】:

      • 或者使用util.promisify,因为回调的结构是(err, result) => { ... }:nodejs.org/api/util.html#util_util_promisify_original
      • ^ 这也是一个选项。虽然公平地说,那个 util 函数可能在内部做同样的事情,或者非常相似的事情:)
      • 感谢您帮助我了解问题所在。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-09
      • 2014-01-02
      • 2020-01-06
      • 2016-09-25
      • 2017-07-31
      • 2020-06-13
      • 1970-01-01
      相关资源
      最近更新 更多