简体   繁体   English

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

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

I just can't seem to wrap my head around chaining queries with promises. 我似乎无法用承诺链接查询链接。 What's confusing me the most is the .then(function(doSomething) part. 令我困惑的是.then(function(doSomething)部分。

What am I supposed to put in the function(doSomething)? 我应该把什么放在函数中(doSomething)? And what does it do? 它做了什么?

Could someone chain these queries for me without using Promise.all but instead using .then()? 有人可以在不使用Promise.all的情况下为我链接这些查询,而是使用.then()吗? So I can learn from this 所以我可以从中吸取教训

SELECT * FROM books where book_id = $1

SELECT * FROM username where username = $2

SELECT * FROM saved where saved_id = $3

The function(doSomething) runs when the previous promise completes successfully, and doSomething is the response. function(doSomething)在前一个promise成功完成时运行, doSomething是响应。 You can chain the promises using then like: 你可以连使用的承诺, 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"));

This will execute the three SQL queries in sequence. 这将按顺序执行三个SQL查询。

However, since you'll most likely want to save the response, you could use async/await for simplicity: 但是,由于您很可能希望保存响应,因此可以使用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];

}

You could also use Promise.all like so: 您也可以像这样使用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")
]);

The purpose of Promises is to enable better flow control of asynchronous operations. Promises的目的是实现异步操作的更好的流控制。 Use Promise.all for cases where you have multiple tasks that must complete, in any order, before code flow can proceed. 对于在代码流可以继续之前,您必须以任何顺序完成多个任务的情况,请使用Promise.all。 Use Promise.then when you have multiple async tasks where each step may partially depend on the result of a previous (eg after querying your books table you query the username table using books.savedByUserId to fetch the appropriate user record). 当您有多个异步任务时,请使用Promise.then,其中每个步骤可能部分取决于之前的结果(例如,在查询您的books表后,您使用books.savedByUserId查询用户名表以获取相应的用户记录)。

Referencing some examples from: https://codeburst.io/node-js-mysql-and-promises-4c3be599909b The author provides a simple mySql wrapper that returns Promises (database.query returns new Promise). 引用一些示例来自: 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 Not to muddy the waters, but in this case three sequential sql queries could likely be replaced by a single query with joins, but I guess that's not really the point of the question. ps不要混淆水域,但在这种情况下,三个连续的SQL查询可能会被一个带连接的查询所取代,但我想这不是问题的关键点。 Let's pretend it's three queries to separate stores, that'd make sense. 让我们假装分开商店的三个查询,这是有道理的。

We use promises which are objects that may produce a single value some time in the future. 我们使用promises,这些promise是将来某个时间可能产生单个值的对象。

As you run query("query string") , it will return a Promise object asynchronously. 当您运行query("query string") ,它将异步返回Promise对象。 Meaning, your app is not going to wait for the query to finish. 意思是,您的应用程序不会等待查询完成。 It is going to start the query process and move on to the next line of code. 它将开始查询过程并继续下一行代码。

So, how do we handle the query when it is done? 那么,我们如何在完成后处理查询?

We use then to process the information that the query returns. then我们使用它来处理查询返回的信息。 then will get triggered when the query successfully completed its process. then将在查询成功完成其进程时触发。

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

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