以前,我已经使用future.wait()
等待一个值return
到下一个函数。 (顺便说一下,我在Meteor中编码)
在读取节点的非阻塞I / O架构之后,我的以下方法(确实有效)是否完全失败了?
我正在做的是将来自以下'requests'函数的返回结果传递给另一个函数。相反,回调方法是最好的惯例吗?
我使用future的唯一原因是因为使用return
会立即执行。我想学习最佳实践,因为我认为我正在使用future添加额外的不必要代码层。
如果我使用回调约定callback(null, result)
,'回调'是否等待将对象传递给参数?
我的代码使用future等待结果:
function requesting(perm_data) {
var f = new future();
request.get('example.com/api/auth_user', {
oauth: {consumer_key:'somekey',
token: perm_data.oauth_token,
token_secret: perm_data.oauth_token_secret
}
}, function response(error, response, body) {
if (!error && response.statusCode === 200) {
var bodyToJson = parser.toJson(body, options)
var userId = bodyToJson.user.id
return f.return(userId)
}
else {
f.throw(error)
}
})
return f.wait()
}
function nextFunction(data) {
//do some thing with data
}
Meteor.methods({
sequenceAsyncFunctions: function() {
try {
var resultOne = requesting()
var resultTwo = nextFuntion(resultOne)
} catch (e) {
//handling my errors
}
}
})
答案 0 :(得分:2)
'回调'等待对象传递给参数
实际上回调不会等待对象。回调是通过您给它的函数的参数调用的。
你可以使用 promise 库之一,例如Q来处理这个
以下是一些更深入地描述它的文章
已指定Promise,您可以在此处查看更多详细信息和库:http://wiki.commonjs.org/wiki/Promises/A
答案 1 :(得分:1)
我注意到你标记了这个问题meteor。 Meteor在服务器上使用Fibers。该软件包使用一种轻量级线程(称为光纤)为您提供协作式多任务处理。这允许你写"阻止"像requesting
这样的函数没有实际阻塞事件循环。 Future
允许您使用Fibers以阻塞方式使用基于回调的node.js函数。
如果没有Fibers,就不可能编写像requesting
那样执行I / O并直接返回结果的函数。相反,你必须通过回调(或使用承诺)。
惯用的流星代码应该利用服务器上的光纤来阻止"功能。这就是核心Meteor API的工作方式,并且在Meteor方法中是必需的。您可能会发现future
更方便,而非使用Meteor.wrapAsync
。
在常规node.js代码中,您可以使用Fibers,但使用function (err, result) {...}
回调或承诺更常见。在浏览器(包括Meteor客户端代码)中,您不能使用Fibers,因此您必须使用回调或承诺。
以下是使用future
,常规回调和承诺对操作进行排序的方法:
// Future
function doTwoThings() {
var future = new Future();
asyncFunction(argument, function (err, result) {
if (err) future.throw(err);
else future.return(result);
});
var result = future.wait();
var future2 = new Future();
anotherAsyncFunction(result, function (err, result2) {
if (err) future2.throw(err);
else future2.return(result2);
});
var result2 = future2.wait();
return result2 + 2;
}
// wrapAsync
var wrappedAsyncFunction = Meteor.wrapAsync(asyncFunction);
var wrappedAnotherAsyncFunction = Meteor.wrapAsync(anotherAsyncFunction);
function doTwoThings() {
var result = wrappedAsyncFunction(argument);
var result2 = wrappedAnotherAsyncFunction(anotherAsyncFunction);
return result2 + 2;
}
// Regular callbacks
function doTwoThings(callback) {
asyncFunction(argument, function (err, result) {
if (err) return callback(err);
anotherAsyncFunction(result, function (err, result2) {
if (err) return callback(err);
callback(null, result2 + 2);
});
});
}
// Promises
function doTwoThings() {
return asyncFunctionReturningPromise(argument).then(function (result) {
return anotherAsyncFunctionReturningPromise(result);
}).then(function (result2) {
return result2 + 2;
});
}