我正在探索node.js中承诺和回调的可能性 我试图找到一种方法让这段代码起作用。目前我面临的问题是,当我调用一个函数并想要使用返回值时,它还没有准备好。我知道自己要做什么,但不知道怎么做。基本上,我必须使insertAddress()返回一个promise(所以我可以使用.then()),或者将回调作为参数。为此,我还认为databaseWork()应该返回一个promise。但我不知道在哪里添加它。 该问题位于&#console; log(out)'中,在设置out变量之前运行(因为insertAddress仍在运行)。 这是我的代码
app.js
-----
const databaseWork = require('./db/mysql.js').databaseWork;
app.use('/test', (req, resp) => {
var address = {
country : "Country",
city : "Randomcity",
street : "Random",
number : 6,
postalcode : "A789",
province : "a province"
}
var out = insertAddress(address); //<== takes time to finish, is not ready when the next console.log finishes
console.log(out);
});
function insertAddress(address){
var rows
databaseWork(
//Following anonymous function contains the actual workload. That has to be done inside a transaction
async (connection) => {
rows = await insertAddressQuery(address,connection);
console.log(rows); //this one waits for insertAddressQuery to be complete
})
return rows; //this will run before insertAddressQuery is complete
}
function insertAddressQuery(address,connection) {
return new Promise( (resolve, reject) => {
//async job
connection.query('INSERT INTO address (country,city,Street,number,postalcode,province) VALUES(?,?,?,?,?,?)', [address.country,'4','5',6,'7','8'] , (err, rows) => {
if (err) {reject(err);}
resolve(rows);
});
});
};
/db/mysql.js
------------
var mysql = require('mysql');
var dbpool = mysql.createPool({
host: process.env.HOST_DB,
user: process.env.USER_DB,
password: process.env.PWD_DB,
database: process.env.DB
});
function databaseWork(workload){
dbpool.getConnection( async (err, connection) => {
await beginTransaction(connection);
await workload(connection);
await commitTransaction(connection)
connection.release();
});
}
function beginTransaction(connection){
return new Promise( (resolve, reject) => {
//async job
connection.beginTransaction( (err) => {
if (err) {reject(err);}
resolve();
});
});
};
function commitTransaction(connection) {
return new Promise( (resolve, reject) => {
//async job
connection.commit( (err) => {
if (err) {reject(err);}
resolve();
});
});
};
exports.databaseWork = databaseWork;
答案 0 :(得分:2)
您可以在databaseWork
:
function databaseWork(workload) {
return new Promise((resolve, reject) => {
dbpool.getConnection(async (err, connection) => {
try {
await beginTransaction(connection);
var result = await workload(connection);
await commitTransaction(connection)
resolve(result);
} catch( err ) {
reject(err)
} finally {
connection.release();
}
});
})
}
Promise
返回的databaseWork
将由workload
的结果解析。现在您可以将insertAddress
更改为:
async function insertAddress(address){
return databaseWork(connection => {
return insertAddressQuery(address,connection);
})
}
然后您需要更改此路线:
app.use('/test', async (req, resp) => {
var address = {
country: "Country",
city: "Randomcity",
street: "Random",
number: 6,
postalcode: "A789",
province: "a province"
}
var out = await insertAddress(address); // use await here to wait for insertAddress to be finished
console.log(out);
});
带有getConnection
函数的* UPDATE 代码返回Promise:
function getConnection() {
return new Promise((resolve, reject) => {
dbpool.getConnection((err, connection) => {
if (err) {
reject(err)
} else {
resolve(connection);
}
})
});
}
async function databaseWork(workload) {
var connection = await getConnection();
var result;
try {
await beginTransaction(connection)
result = await workload(connection)
await commitTransaction(connection)
} catch (err) {
// a rollback might be neccesaary at that place
throw err
} finally {
connection.release();
}
return result;
}
答案 1 :(得分:0)
一种方法是使用async await。
var example = async (req, res) => {
var response = await myAsyncTask();
// this will get logged once the async task finished running.
console.log(response)
}
// Use async await to get response
var myAsyncTask = async () => {
try {
var response = await asyncTaskINeedDataFrom()
return response;
}
catch(err) {
return console.log(err);
}
}