繁体   English   中英

混淆了如何使用.then()使用promises链接查询

[英]Confused on how to chain queries using promises using .then()

我似乎无法用承诺链接查询链接。 令我困惑的是.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

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")
]);

Promises的目的是实现异步操作的更好的流控制。 对于在代码流可以继续之前,您必须以任何顺序完成多个任务的情况,请使用Promise.all。 当您有多个异步任务时,请使用Promise.then,其中每个步骤可能部分取决于之前的结果(例如,在查询您的books表后,您使用books.savedByUserId查询用户名表以获取相应的用户记录)。

引用一些示例来自: https ://codeburst.io/node-js-mysql-and-promises-4c3be599909b作者提供了一个简单的mySql包装器,它返回Promises(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
    })

ps不要混淆水域,但在这种情况下,三个连续的SQL查询可能会被一个带连接的查询所取代,但我想这不是问题的关键点。 让我们假装分开商店的三个查询,这是有道理的。

我们使用promises,这些promise是将来某个时间可能产生单个值的对象。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM