1

New to async and struggling. As an example below I wish to init a table then process it's contents by: a) Remove old data b) Insert a new record c) Read the table into an array d) Display the array

'use strict';


// ================================================================================
// Module dependencies
var pgp      = require('pg-promise')();


// ================================================================================
//Configure the database connection
var config = {
  user:               'user', //env var: PGUSER 
  database:           'database', //env var: PGDATABASE 
  password:           'password', //env var: PGPASSWORD
};
var db = pgp(config);


// ================================================================================
// Initialise rhe variables
var customers = [];


// ================================================================================
// Initialise table
db.none("DELETE FROM testing")
  .then(function(data) {
    console.log("Deleted old records");
    // success;
  })
  .catch(function(error) {
    console.log(error);
  });

db.none("INSERT INTO testing (firstname, surname) VALUES ('Bob', 'Brown')")
  .then(function(data) {
    console.log("Inserted new record");
    // success;
  })
  .catch(function(error) {
    console.log(error);
  });


// ================================================================================
// Display records
db.any("SELECT * FROM testing")
  .then(function(data) {
    console.log("Looping records");
    data.forEach(function(row, index, data) {
      customers.push(row.firstname, row.lastname);
      console.log(row);
    });
  })
  .catch(function(error) {
    console.log(error);
  });

console.log("The customers are:");
console.log(customers);

The output is not as desired but somewhat as expected. Interestingly after "Inserted new records" there is a 30 second wait before the command prompt is retuned.

The customers are:
[]
Looping records
anonymous {
  id: 3,
  firstname: 'Bob',
  surname: 'Brown',
  created: 2016-08-03T01:43:34.880Z }
Deleted old records
Inserted new record

My question is ultimately with async programming surely there are scenarios where actions need to be performed in sequence such as the example above and in such a scenario how can this be coded in an async environment such as node.js.

4

2 に答える 2

2

.thenデータベースにアクセスする promise をサポートするライブラリを使用しているため、次のメソッドの各ステップを実行する必要があります。メソッド内のステップを実行しない場合.then、各ステートメントは、その「ティック」のステートメントがなくなるまで、現在の「ティック」で実行されます。非同期メソッド (で呼び出されるdb.none(...)) は、将来の「ティック」で実行されます。これにより、最後の 2 つのconsole.logステートメントが最初に出力されるステートメントとして表示されます。

ワークフローを改善するために、コードを次のように変更してみてください。

'use strict';


// ================================================================================
// Module dependencies
var pgp      = require('pg-promise')();


// ================================================================================
//Configure the database connection
var config = {
  user:               'user', //env var: PGUSER 
  database:           'database', //env var: PGDATABASE 
  password:           'password', //env var: PGPASSWORD
};
var db = pgp(config);


// ================================================================================
// Initialise rhe variables
var customers = [];


// ================================================================================
// Initialise table
db.none("DELETE FROM testing")
  .then(function(data) {
    console.log("Deleted old records");
    // success;

    return db.none("INSERT INTO testing (firstname, surname) VALUES ('Bob', 'Brown')");
  })
  .then(function(data) {
    console.log("Inserted new record");
    // success;

    // Display records
    return db.any("SELECT * FROM testing");
  })
  .then(function(data) {
    console.log("Looping records");
    data.forEach(function(row, index, data) {
      customers.push(row.firstname, row.lastname);
      console.log(row);
    });
  })
  .then(function() {
    console.log("The customers are:");
    console.log(customers);
  })
  .catch(function(error) {
    console.log(error);
  });

各アクション/ステップが別の.thenメソッドでどのように表示されるかを確認してください。また、db.メソッドはプロミスを返すため、メソッド内でそれらを返すことができ、そのステートメントが終了する.thenと次が実行されます。.then

お役に立てれば。

于 2016-08-03T02:54:06.433 に答える
1

解決策は、クエリ間に依存関係があるかどうかによって異なります。それらが依存している場合は、約束どおりにチェーンします。それ以外の場合は、バッチとして並行して実行できます。

'use strict';

var promise = require('bluebird');

var pgp = require('pg-promise')({
    promiseLib: promise // use a custom promise library
});

var config = {
    user: 'user', //env var: PGUSER 
    database: 'database', //env var: PGDATABASE 
    password: 'password', //env var: PGPASSWORD
};

var db = pgp(config);

function prepareCustomers(t) {
    return t.batch([
        t.none('DELETE FROM testing'),
        t.none('INSERT INTO testing VALUES($1, $2)', ['Bob', 'Brown']),
        t.any('SELECT * FROM testing')
    ])
        .then(data=>data[2]); // get results from the select query
}

db.tx(prepareCustomers)
    .then(customers=> {
        console.log(customers);
    })
    .catch(error=> {
        console.log(error);
    })
    .finally(pgp.end); // only call pgp.end when exiting the application

また、このようなデータベースに変更を加える場合、通常は上記の例に示すようにトランザクションを使用します。

興味深いことに、"Inserted new records" の後、コマンド プロンプトが再調整されるまで 30 秒間待機します。

ライブラリの初期化解除を参照してください

于 2016-08-05T15:54:34.990 に答える