Lio*_*rez 91 javascript node.js promise q bluebird
我有一个简单的节点模块,它连接到一个数据库,并有几个接收数据的函数,例如这个函数:
dbConnection.js:
import mysql from 'mysql';
const connection = mysql.createConnection({
host: 'localhost',
user: 'user',
password: 'password',
database: 'db'
});
export default {
getUsers(callback) {
connection.connect(() => {
connection.query('SELECT * FROM Users', (err, result) => {
if (!err){
callback(result);
}
});
});
}
};
Run Code Online (Sandbox Code Playgroud)
该模块将从不同的节点模块以这种方式调用:
app.js:
import dbCon from './dbConnection.js';
dbCon.getUsers(console.log);
Run Code Online (Sandbox Code Playgroud)
我想使用promises而不是回调来返回数据.到目前为止,我已经阅读了以下线程中的嵌套promise:使用嵌套Promise编写清洁代码,但我找不到任何对这个用例来说足够简单的解决方案.result使用承诺返回的正确方法是什么?
Rob*_*ann 97
Promise课程我建议看看MDN的Promise文档,它为使用Promise提供了一个很好的起点.或者,我确信网上有很多教程.:)
注意:现代浏览器已经支持Promises的ECMAScript 6规范(参见上面链接的MDN文档),我假设你想要使用原生实现,没有第三方库.
至于一个实际的例子......
基本原理是这样的:
resolve和reject这可能看起来很多,所以这是一个实际的例子.
exports.getUsers = function getUsers () {
// Return the Promise right away, unless you really need to
// do something before you create a new Promise, but usually
// this can go into the function below
return new Promise((resolve, reject) => {
// reject and resolve are functions provided by the Promise
// implementation. Call only one of them.
// Do your logic here - you can do WTF you want.:)
connection.query('SELECT * FROM Users', (err, result) => {
// PS. Fail fast! Handle errors first, then move to the
// important stuff (that's a good practice at least)
if (err) {
// Reject the Promise with an error
return reject(err)
}
// Resolve (or fulfill) the promise with data
return resolve(result)
})
})
}
// Usage:
exports.getUsers() // Returns a Promise!
.then(users => {
// Do stuff with users
})
.catch(err => {
// handle errors
})
Run Code Online (Sandbox Code Playgroud)
在Node.js 7.6中,使用async/await支持升级了v8 JavaScript编译器.您现在可以将函数声明为async,这意味着它们会自动返回Promise在异步函数完成执行时解析的函数.在此函数中,您可以使用await关键字等待另一个Promise结算.
这是一个例子:
exports.getUsers = async function getUsers() {
// We are in an async function - this will return Promise
// no matter what.
// We can interact with other functions which return a
// Promise very easily:
const result = await connection.query('select * from users')
// Interacting with callback-based APIs is a bit more
// complicated but still very easy:
const result2 = await new Promise((resolve, reject) => {
connection.query('select * from users', (err, res) => {
return void err ? reject(err) : resolve(res)
})
})
// Returning a value will cause the promise to be resolved
// with that value
return result
}
Run Code Online (Sandbox Code Playgroud)
Mad*_*iha 31
使用bluebird,您可以使用Promise.promisifyAll(和Promise.promisify)向任何对象添加Promise就绪方法.
var Promise = require('bluebird');
// Somewhere around here, the following line is called
Promise.promisifyAll(connection);
exports.getUsersAsync = function () {
return connection.connectAsync()
.then(function () {
return connection.queryAsync('SELECT * FROM Users')
});
};
Run Code Online (Sandbox Code Playgroud)
并使用这样的:
getUsersAsync().then(console.log);
Run Code Online (Sandbox Code Playgroud)
要么
// Spread because MySQL queries actually return two resulting arguments,
// which Bluebird resolves as an array.
getUsersAsync().spread(function(rows, fields) {
// Do whatever you want with either rows or fields.
});
Run Code Online (Sandbox Code Playgroud)
蓝鸟支持很多功能,其中之一是处置器,它可以让你安全地处理一个连接后的帮助下结束了Promise.using和Promise.prototype.disposer.这是我的应用程序中的一个示例:
function getConnection(host, user, password, port) {
// connection was already promisified at this point
// The object literal syntax is ES6, it's the equivalent of
// {host: host, user: user, ... }
var connection = mysql.createConnection({host, user, password, port});
return connection.connectAsync()
// connect callback doesn't have arguments. return connection.
.return(connection)
.disposer(function(connection, promise) {
//Disposer is used when Promise.using is finished.
connection.end();
});
}Run Code Online (Sandbox Code Playgroud)
然后像这样使用它:
exports.getUsersAsync = function () {
return Promise.using(getConnection()).then(function (connection) {
return connection.queryAsync('SELECT * FROM Users')
});
};
一旦promise与值一起解析(或拒绝一个Error),这将自动结束连接.
asm*_*mud 10
Node.js版本8.0.0+:
您不必再使用bluebird来宣传节点API方法.因为,从版本8+开始,您可以使用本机util.promisify:
const util = require('util');
const connectAsync = util.promisify(connection.connectAsync);
const queryAsync = util.promisify(connection.queryAsync);
exports.getUsersAsync = function () {
return connectAsync()
.then(function () {
return queryAsync('SELECT * FROM Users')
});
};
Run Code Online (Sandbox Code Playgroud)
现在,不必使用任何第三方库来进行promisify.
| 归档时间: |
|
| 查看次数: |
91584 次 |
| 最近记录: |