如何正确构造一个循环以确保后续的promise调用和链式logger.log(res)通过迭代同步运行?(蓝鸟)
db.getUser(email).then(function(res) { logger.log(res); }); // this is a promise
Run Code Online (Sandbox Code Playgroud)
我尝试了以下方法(来自http://blog.victorquinn.com/javascript-promise-while-loop的方法)
var Promise = require('bluebird');
var promiseWhile = function(condition, action) {
var resolver = Promise.defer();
var loop = function() {
if (!condition()) return resolver.resolve();
return Promise.cast(action())
.then(loop)
.catch(resolver.reject);
};
process.nextTick(loop);
return resolver.promise;
});
var count = 0;
promiseWhile(function() {
return count < 10;
}, function() {
return new Promise(function(resolve, reject) {
db.getUser(email)
.then(function(res) {
logger.log(res);
count++;
resolve();
});
});
}).then(function() {
console.log('all done');
}); …
Run Code Online (Sandbox Code Playgroud) 我有一个简单的节点模块,它连接到一个数据库,并有几个接收数据的函数,例如这个函数:
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
使用承诺返回的正确方法是什么?
我无法理解将.catch
BEFORE和AFTER放在嵌套的promise中之间的区别.
备选方案1:
test1Async(10).then((res) => {
return test2Async(22)
.then((res) => {
return test3Async(100);
}).catch((err) => {
throw "ERROR AFTER THEN";
});
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
Run Code Online (Sandbox Code Playgroud)
备选方案2:
test1Async(10).then((res) => {
return test2Async(22)
.catch((err) => {
throw "ERROR BEFORE THEN";
})
.then((res) => {
return test3Async(100);
});
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
Run Code Online (Sandbox Code Playgroud)
每个函数的行为如下,如果number为<0
test2则test1失败,如果number为,则test1失败,如果number为number则> 10
test3失败100
.在这种情况下,test2只是失败了.
我尝试运行并使test2Async失败,BEFORE和AFTER之后的行为方式相同,并且没有执行test3Async.有人可以向我解释将捕捞放在不同地方的主要区别吗?
在每个函数中我console.log('Running test X')
都要检查它是否被执行.
这个问题出现是因为我发布的上一个帖子如何将嵌套回调转换为promise?.我认为这是一个不同的问题,值得发布另一个主题.
我正在使用蓝鸟,我看到两种方法将同步函数解析为Promise,但我没有得到两种方式之间的差异.看起来堆栈跟踪有点不同,所以它们不仅仅是一个alias
,对吧?
那么首选方式是什么?
方式A.
function someFunction(someObject) {
return new Promise(function(resolve) {
someObject.resolved = true;
resolve(someObject);
});
}
Run Code Online (Sandbox Code Playgroud)
方式B.
function someFunction(someObject) {
someObject.resolved = true;
return Promise.resolve(someObject);
}
Run Code Online (Sandbox Code Playgroud) 我正在研究与Koa一起构建一个Web应用程序,但是我还没有完全了解Hows,whens以及为什么选择 - 并应用 - 支持"使异步更容易"的技术/方法(下面列出).
总体而言,关于此主题的网络上的不同指南仍然使事情变得模糊,特别是在不断发展的最佳实践方面,或者至少是更好的方法,以及在什么情况下.在网络上似乎很少或根本没有把它全部放在上下文中.
我希望对这个大屁股庞大的帖子做出回应可以纠正这个问题.也许下面的问题可以激发某人写一篇完整的博客文章等来解决这个问题.我的感觉是,我甚至没有接近唯一一个从中受益的人.
因此,如果明亮的社区能够帮助回答并明确以下列出的技术(粗体字),我会很高兴:
- a)如何以及在何种情况下(如适用)它们相互补充,补充,替代和/或重叠解决方案?
- b)在速度性能,错误处理容易性和调试简易性方面,他们的权衡是什么?
- c)何时,何地以及为什么使用"this"与"that"技术,技术组合和/或方法更好?
- d)哪些技术或方法(如果有的话)可能是"调光星".
(希望可以很好地解释作为答案一部分的意见.)
==============================
技术:
*Koa*
我的理解:
Koa是构建节点应用程序的最小基础,旨在利用ECMAScript-6功能,其中一个特性是生成器.
*Co*
我的理解:
- Co是一个用于运行ECMAScript-6生成器(它们是Node .011和谐的本机)的实用程序库,目的是为了编写用于运行和管理生成器的样板代码的一些/多(?)需要.
- Co本质上是Koa(?)的一部分.
具体问题:
- 如果以及如何在Koa中使用Co而不是在非Koa上下文中使用Co.换句话说,Koa是完全立面Co吗?
- 如果有更好的产品库,Co可以用Koa替换其他类似的生成器库吗?有吗?
*承诺"Q"和Bluebird*等图书馆
我的理解:
- 它们在某种意义上是"polyfill"用于实现Promises/A +规范,如果Node直到运行该规范.
- 他们还有一些非规范的便利工具,用于促进使用承诺,例如Bluebird的promisfyAll实用程序.
具体问题:
- 我的理解是ECMAScript-6规范确实/将在很大程度上反映Promises/A +规范,但即便如此,Node 0.11v和谐本身并不实现Promises.(这是正确的吗?)但是当它出现时,Q和Bluebird等技术是否正在逐步推出?
- 我读过"Q"和Bluebird支持生成器的内容.这是什么意思?例如,它在某种程度上是否意味着它们在某种程度上提供了与Co相同的效用,如果是这样,那么在多大程度上呢?
*Thunk和Promises*
我认为我对它们是什么有一个公平的处理,但希望有人可以提供一个简洁明了的"电梯间距"定义每个是什么,当然,如上所述,解释何时使用一个与另一个 - 在Koa环境中而不是在它中.
具体问题:
- 使用像Thunkify(github com/visionmedia/node-thunkify)使用像Bluebird这样的东西的赞成和利弊?
==============================
为了给这篇文章及其问题提供一些进一步的背景,如果可以对以下网页中提供的Koa技术进行讨论和对比(特别是在优点与缺点的基础上),这可能会很有趣:
- a)www.marcusoft.net/2014/03/koaintro.html(在哪里是thunk或promises,还是我没有看到什么?)
- b)strongloop.com/strongblog/node-js-express-introduction-koa-js-zone(同样,那里是thunk还是promises?)
- c)github.com/koajs/koa/blob/master/docs/guide.md("下一个"参数等于什么,设置它和在哪里?)
- d)blog.peterdecroos.com/blog/2014/01/22/javascript-generators-first-impressions(不是在Koa上下文中,但是介绍了Co与promise库(Bluebird)的使用,所以我假设这里提供的技术/模式借出本身是用在Koa(?).如果是这样,那么有多好?
谢谢大家!
我在Node.js下使用Bluebird promise库,这太棒了!但我有一个问题:
如果你看一下Node的child_process.exec和child_process.execFile的文档,你会发现这两个函数都返回了一个ChildProcess对象.
那么推荐这种功能的方法是什么?
请注意以下工作(我得到一个Promise对象):
var Promise = require('bluebird');
var execAsync = Promise.promisify(require('child_process').exec);
var execFileAsync = Promise.promisify(require('child_process').execFile);
Run Code Online (Sandbox Code Playgroud)
但是如何才能访问原始Node.js函数的原始返回值?(在这些情况下,我需要能够访问最初返回的ChildProcess对象.)
任何建议将不胜感激!
编辑:
下面是一个使用child_process.exec函数返回值的示例代码:
var exec = require('child_process').exec;
var child = exec('node ./commands/server.js');
child.stdout.on('data', function(data) {
console.log('stdout: ' + data);
});
child.stderr.on('data', function(data) {
console.log('stderr: ' + data);
});
child.on('close', function(code) {
console.log('closing code: ' + code);
});
Run Code Online (Sandbox Code Playgroud)
但是,如果我将使用exec函数的promisified版本(上面的execAsync),那么返回值将是一个promise,而不是ChildProcess对象.这是我正在谈论的真正问题.
我正在使用bluebird库,需要发出一系列HTTP请求,并需要将一些响应数据发送到下一个HTTP请求.我已经构建了一个处理我的请求的函数callhttp()
.这需要一个URL和POST的正文.
我这样称呼它:
var payload = '{"Username": "joe", "Password": "password"}';
var join = Promise.join;
join(
callhttp("172.16.28.200", payload),
callhttp("172.16.28.200", payload),
callhttp("172.16.28.200", payload),
function (first, second, third) {
console.log([first, second, third]);
});
Run Code Online (Sandbox Code Playgroud)
第一个请求获取一个API密钥,需要将其传递给第二个请求,依此类推.如何从第一个请求获取响应数据?
UPDATE
这是callhttp
功能:
var Promise = require("bluebird");
var Request = Promise.promisify(require('request'));
function callhttp(host, body) {
var options = {
url: 'https://' + host + '/api/authorize',
method: "POST",
headers: {
'content-type': 'application/json'
},
body: body,
strictSSL: false
};
return Request(options).spread(function (response) {
if (response.statusCode == 200) {
// …
Run Code Online (Sandbox Code Playgroud) 我找到了一个使用promises的现有库,但它不使用bluebird.库函数不与所有的额外功能蓝鸟确实喜欢.map()
或.tap()
.我如何将"正常"或"非蓝鸟"的承诺转换为蓝鸟承诺,蓝鸟提供的所有额外功能?
我尝试将现有的承诺包装起来Promise.promisify
,Promise.resolve
而且似乎都没有效果.
我尝试使用Angular和Bluebird的承诺:
HTML:
<body ng-app="HelloApp">
<div ng-controller="HomeController">{{name}} {{also}}</div>
</body>
Run Code Online (Sandbox Code Playgroud)
JS:
// javascript
var app = angular.module('HelloApp', []);
app.controller("HomeController", function ($scope) {
var p = Promise.delay(1000).then(function () {
$scope.name = "Bluebird!";
console.log("Here!", $scope.name);
}).then(function () {
$scope.also = "Promises";
});
$scope.name = "$q";
$scope.also = "promises";
});
window.app = app;
Run Code Online (Sandbox Code Playgroud)
[ 小提琴 ]
但是,不管我尝试了什么,它都会保持停留"$q promises"
并且不会更新.除非我添加了一本$scope.$apply
我宁愿避免使用的手册.
(我知道这是可能的,因为$ q会这样做)
我正在使用Bluebird 2.0,我在这里.
我想使用promises在JavaScript中使用aws-sdk.
而不是默认的回调样式:
dynamodb.getItem(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
Run Code Online (Sandbox Code Playgroud)
我想要使用承诺风格:
dynamoDb.putItemAsync(params).then(function(data) {
console.log(data); // successful response
}).catch(function(error) {
console.log(err, err.stack); // an error occurred
});
Run Code Online (Sandbox Code Playgroud)