简体   繁体   English

在蓝鸟中使用“ .then”链接异步功能。 什么是最好的方法?

[英]Chaining async functions in bluebird with “.then”. What is the best way?

I am currently learning about bluebird and came up with this bit of code (Using Express.js and Mongoose) to test it out: 我目前正在学习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);
  });

The function in my first .then call is only returning another function. 我的第一个.then调用中的函数仅返回另一个函数。 Therefore I was wondering, if there is a way to pass connectDB directly to .then and make it work. 因此,我想知道是否有一种方法可以将connectDB直接传递给.then并使之工作。 Something like this: 像这样:

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. 因此,我想知道是否有一种方法可以将connectDB直接传递给.then并使之工作。

Yes, that's possible via something called currying (after Haskell Curry, the mathematician). 是的,这可以通过称为currying的东西来实现(在数学家Haskell Curry之后)。 You'll also see it called partial application . 您还将看到它称为部分应用程序 Basically, you create a new function that, when called, will call the original with the arguments you specify when creating it. 基本上,您将创建一个新函数,该函数在被调用时将使用在创建原始函数时指定的参数来调用原始函数。

JavaScript has Function#bind which does two things: 1. Sets what this will be, and 2. Does currying. JavaScript有Function#bind其做了两两件事:1,设置什么this将是,和2不钻营。 It doesn't look like your example cares what this will be, so we can use it for this. 看起来您的示例并不关心this将是什么,因此我们可以将其用于此。

Ex: 例如:

startServer(3000)
  .then(connectDB.bind(null, MongoURI))
  .catch((e) => {
    console.log('Exception ' + e);
  });

The null is for the thisArg argument, which we're effectively not using. null表示thisArg参数,我们实际上并未使用它。

Here's a simpler example, just to illustrate: 这是一个更简单的示例,仅用于说明:

 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> 

Whether it's desireable is another question (and probably an opinion-based one). 是否可取是另一个问题(可能是基于意见的问题)。 Your original with the arrow function is nice and clear and not likely to be expensive (in terms of memory or time). 带有箭头功能的原件清晰美观,而且不太昂贵(就内存或时间而言)。 But it is possible to do ths, yes. 但是有可能做,是的。


If you wanted the function to receive the this it was called with (probably not in your case, but it's fairly common in, say, jQuery event handlers in browser-based JavaScript), it's also easy to write a function that just does the currying without the this stuff Function#bind does. 如果你想接收功能this它被称为用(可能不是你的情况,但它是相当普遍的,也就是说,jQuery的事件处理程序在基于浏览器的JavaScript),它也很容易编写一个函数,只是做了柯里没有this东西, Function#bind做。 This answer has a very simple, un-optimized example. 这个答案有一个非常简单的,未优化的示例。

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

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