【问题标题】:Confused on how to chain queries using promises using .then()对如何使用 .then() 使用 Promise 链接查询感到困惑
【发布时间】:2019-10-29 13:34:13
【问题描述】:

我似乎无法用 Promise 链接查询。最让我困惑的是 .then(function(doSomething) 部分。

我应该在函数(doSomething)中添加什么?它有什么作用?

有人可以在不使用 Promise.all 而是使用 .then() 的情况下为我链接这些查询吗?所以我可以从中学习

SELECT * FROM books where book_id = $1

SELECT * FROM username where username = $2

SELECT * FROM saved where saved_id = $3

【问题讨论】:

  • 您是否已经有一个返回承诺的函数来执行这些查询?您是否使用特定的数据库库?
  • 您是否已有使用Promise.all的工作代码?
  • 想要then回调中添加什么?你知道回调一般是如何工作的吗?你读过then 方法的文档吗?

标签: javascript node.js ecmascript-6 promise


【解决方案1】:

Promises 的目的是为了更好地控制异步操作​​。将 Promise.all 用于在代码流继续之前必须以任何顺序完成多个任务的情况。使用 Promise。然后当您有多个异步任务,其中每个步骤可能部分依赖于前一个的结果时(例如,在查询您的书籍表后,您使用 books.savedByUserId 查询用户名表以获取适当的用户记录)。

参考一些例子来自:https://codeburst.io/node-js-mysql-and-promises-4c3be599909b作者提供了一个简单的返回Promise的mySql包装器(database.query返回新的Promise)。

//In this example Promise.all executes the queries independently, but provides an
//effective tool to resume your work after all are completed. The order in which
//they complete may be random/indeterminate.
var bookQuery = database.query( 'SELECT * FROM books where book_id = $1' );
var userQuery = database.query( 'SELECT * FROM username where username = $2' );
var saveQuery = database.query( 'SELECT * FROM saved where saved_id = $3' );

Promise.all([bookQuery,userQuery,saveQuery]).then(function(results){
    //resume whatever processing that should happen afterwards
    //For instance, perhaps form fields in your UI require these datasets to be loaded
    //before displaying the UI.
    myDialog.open()
});

// In this example, things are done sequentially, this makes the most sense 
// when the result of each operation feeds into the next. Since your queries don't
// rely on each other, this is not ideally depicted.
let bookRows, userRows, savedRows ;
database.query( 'SELECT * FROM books where book_id = $1' )
    .then( rows => {
        bookRows = rows;
        return database.query( 'SELECT * FROM username where username = $2' );
    })
    .then( rows => {
        userRows = rows;
        return database.query( 'SELECT * FROM saved where saved_id = $3' );
    })
    .then( rows => {
        savedRows = rows;
        return database.close();
    })
    .then( () => {
        // do something with bookRows, userRows, savedRows
    }
    .catch( err => {
        // handle the error
    })

附言不要搅浑水,但在这种情况下,三个连续的 sql 查询可能会被一个带有连接的查询替换,但我想这并不是问题的重点。让我们假设这是三个查询来分隔商店,这是有道理的。

【讨论】:

    【解决方案2】:

    function(doSomething) 在前一个 promise 成功完成时运行,doSomething 是响应。您可以使用then 链接承诺,例如:

    query("SELECT * FROM books where book_id = $1")
      .then(() => query("SELECT * FROM username where username = $2"))
      .then(() => query("SELECT * FROM saved where saved_id = $3"));
    

    这将依次执行三个 SQL 查询。

    但是,由于您很可能希望保存响应,因此为简单起见,您可以使用 async/await

    async function threeQueries() {
    
      //Fetch all three queries in sequence
      let queryOne = await query("SELECT * FROM books where book_id = $1");
      let queryTwo = await query("SELECT * FROM username where username = $2");
      let queryThree = await query("SELECT * FROM saved where saved_id = $3");
    
      //Extract the response text from our queries
      let resultOne = await queryOne.text();
      let resultTwo = await queryTwo.text();
      let resultThree = await queryThree.text();
    
      //Return the responses from the function
      return [resultOne, resultTwo, resultThree];
    
    }
    

    你也可以像这样使用Promise.all

    Promise.all([
      query("SELECT * FROM books where book_id = $1"), 
      query("SELECT * FROM username where username = $2"), 
      query("SELECT * FROM saved where saved_id = $3")
    ]);
    

    【讨论】:

    • 如果其中一个查询失败,我将如何处理错误?每次查询完成后,我是否需要在 .then( ( ) 方法中解析每个承诺?
    • OP 不能与Promise.all 并行运行它们吗?我没有看到任何需要链接的东西,我猜 OP 想要一个实际需要链接的例子,重要的是你可以通过承诺获得链的最后一个值,如果他们真的需要的话链式,可能是他们需要的。
    • 是的@JuanMendes - 我会将其添加到我的答案中。
    【解决方案3】:

    我们使用承诺,它们是可能在未来某个时间产生单个值的对象。

    当您运行query("query string") 时,它将异步返回一个 Promise 对象。这意味着,您的应用不会等待查询完成。它将开始查询过程并继续执行下一行代码。

    那么,查询完成后我们如何处理呢?

    我们使用then 来处理查询返回的信息。 then 将在查询成功完成其进程时触发。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多