使用“.then”在 bluebird 中链接异步函数。什么是最好的方法?
Chaining async functions in bluebird with ".then". What is the best way?
我目前正在学习 bluebird 并想出了这段代码(使用 Express.js 和 Mongoose)来测试它:
let startServer = Promise.promisify(app.listen, app);
let connectDB = Promise.promisify(mongoose.connect, mongoose);
startServer(3000)
.then(() => connectDB(MongoURI))
.catch((e) => {
console.log('Exception ' + e);
});
我的第一个 .then 调用中的函数只返回另一个函数。
因此我想知道,是否有办法将 connectDB 直接传递给 .then 并使其工作。像这样:
startServer(3000)
.then(connectDB, MongoURI)
.catch((e) => {
console.log('Exception ' + e);
});
Therefore I was wondering, if there is a way to pass connectDB directly to .then and make it work.
是的,这可以通过称为 currying 的东西实现(在数学家 Haskell Curry 之后)。您还会看到它被称为 partial application。基本上,您创建了一个新函数,该函数在被调用时将使用您在创建时指定的参数调用原始函数。
JavaScript 有 Function#bind
做两件事:1. 设置 this
的内容,以及 2. 柯里化。看起来您的示例并不关心 this
会是什么,因此我们可以为此使用它。
例如:
startServer(3000)
.then(connectDB.bind(null, MongoURI))
.catch((e) => {
console.log('Exception ' + e);
});
null
用于 thisArg
参数,我们实际上没有使用它。
这里有一个更简单的例子,只是为了说明:
function foo(a, b) {
snippet.log("a = " + a);
snippet.log("b = " + b);
}
// "Curry" 1 as the first arg
var f1 = foo.bind(null, 1);
// Call the resulting function:
f1(2); // "a = 1, b = 2"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
它是否 可取 是另一个问题(可能是基于意见的问题)。您带有箭头功能的原件非常清晰,而且不太可能很昂贵(就内存或时间而言)。但是可能这样做,是的。
如果您希望该函数接收 this
它被调用(可能不是您的情况,但它在基于浏览器的 jQuery 事件处理程序中很常见 JavaScript),也很容易编写一个只进行柯里化而没有 this
东西 Function#bind
的函数。 有一个非常简单、未优化的示例。
我目前正在学习 bluebird 并想出了这段代码(使用 Express.js 和 Mongoose)来测试它:
let startServer = Promise.promisify(app.listen, app);
let connectDB = Promise.promisify(mongoose.connect, mongoose);
startServer(3000)
.then(() => connectDB(MongoURI))
.catch((e) => {
console.log('Exception ' + e);
});
我的第一个 .then 调用中的函数只返回另一个函数。 因此我想知道,是否有办法将 connectDB 直接传递给 .then 并使其工作。像这样:
startServer(3000)
.then(connectDB, MongoURI)
.catch((e) => {
console.log('Exception ' + e);
});
Therefore I was wondering, if there is a way to pass connectDB directly to .then and make it work.
是的,这可以通过称为 currying 的东西实现(在数学家 Haskell Curry 之后)。您还会看到它被称为 partial application。基本上,您创建了一个新函数,该函数在被调用时将使用您在创建时指定的参数调用原始函数。
JavaScript 有 Function#bind
做两件事:1. 设置 this
的内容,以及 2. 柯里化。看起来您的示例并不关心 this
会是什么,因此我们可以为此使用它。
例如:
startServer(3000)
.then(connectDB.bind(null, MongoURI))
.catch((e) => {
console.log('Exception ' + e);
});
null
用于 thisArg
参数,我们实际上没有使用它。
这里有一个更简单的例子,只是为了说明:
function foo(a, b) {
snippet.log("a = " + a);
snippet.log("b = " + b);
}
// "Curry" 1 as the first arg
var f1 = foo.bind(null, 1);
// Call the resulting function:
f1(2); // "a = 1, b = 2"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
它是否 可取 是另一个问题(可能是基于意见的问题)。您带有箭头功能的原件非常清晰,而且不太可能很昂贵(就内存或时间而言)。但是可能这样做,是的。
如果您希望该函数接收 this
它被调用(可能不是您的情况,但它在基于浏览器的 jQuery 事件处理程序中很常见 JavaScript),也很容易编写一个只进行柯里化而没有 this
东西 Function#bind
的函数。