运行 node 中的一系列异步函数未来需要在哪里?
Where is future necessary to run a sequence of async functions in node?
以前,我使用 future.wait()
来等待一个值,然后再 return
它到下一个函数。 (顺便说一句,我正在用 Meteor 编码)
在阅读了节点的非阻塞I/O架构之后,我的以下方法(确实有效)是否完全违背了目的?
我所做的是将以下'requesting'函数的返回结果传递给另一个函数。相反,回调方法是最好的约定吗?
我使用 future 的唯一原因是因为使用 return
会立即执行。我想学习最佳实践,因为我认为我正在使用 future 添加额外的不必要代码层。
如果我使用回调约定 callback(null, result)
,是否 'callback' 等待对象被传递到参数中?
我的代码使用 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
}
}
})
'callback' wait for objects to be passed into the arguments
实际上回调并不等待对象。回调由您为其提供参数的函数使用参数调用。
您可以使用 promise 库之一,例如 Q 来处理这个问题
这里有一些文章更深入地描述了它
- https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/
- Nodeschool 教程:https://github.com/stevekane/promise-it-wont-hurt
已指定承诺,您可以在此处查看更多详细信息和库:http://wiki.commonjs.org/wiki/Promises/A
我注意到您在服务器上标记了这个问题 meteor. Meteor uses Fibers。该软件包使用一种轻量级线程(称为纤程)为您提供协作式多任务处理。这使您可以像 requesting
一样编写 "blocking" 函数,而不会实际阻塞事件循环。 Future
允许您使用纤程以阻塞方式使用基于回调的 node.js 函数。
如果没有 Fibers,就不可能编写出像您的 requesting
这样直接执行 I/O 和 returns 结果的函数。相反,您必须传递回调(或使用承诺)。
惯用的 Meteor 代码应该使用服务器上的 Fibers 来实现 "blocking" 功能。这就是核心 Meteor API 的工作方式,并且在 Meteor 方法中是必需的。您可能会发现 Meteor.wrapAsync
比使用 future
更方便。
在常规 node.js 代码中,您可以使用纤程,但更常见的是使用 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;
});
}
以前,我使用 future.wait()
来等待一个值,然后再 return
它到下一个函数。 (顺便说一句,我正在用 Meteor 编码)
在阅读了节点的非阻塞I/O架构之后,我的以下方法(确实有效)是否完全违背了目的?
我所做的是将以下'requesting'函数的返回结果传递给另一个函数。相反,回调方法是最好的约定吗?
我使用 future 的唯一原因是因为使用 return
会立即执行。我想学习最佳实践,因为我认为我正在使用 future 添加额外的不必要代码层。
如果我使用回调约定 callback(null, result)
,是否 'callback' 等待对象被传递到参数中?
我的代码使用 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
}
}
})
'callback' wait for objects to be passed into the arguments
实际上回调并不等待对象。回调由您为其提供参数的函数使用参数调用。
您可以使用 promise 库之一,例如 Q 来处理这个问题
这里有一些文章更深入地描述了它
- https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/
- Nodeschool 教程:https://github.com/stevekane/promise-it-wont-hurt
已指定承诺,您可以在此处查看更多详细信息和库:http://wiki.commonjs.org/wiki/Promises/A
我注意到您在服务器上标记了这个问题 meteor. Meteor uses Fibers。该软件包使用一种轻量级线程(称为纤程)为您提供协作式多任务处理。这使您可以像 requesting
一样编写 "blocking" 函数,而不会实际阻塞事件循环。 Future
允许您使用纤程以阻塞方式使用基于回调的 node.js 函数。
如果没有 Fibers,就不可能编写出像您的 requesting
这样直接执行 I/O 和 returns 结果的函数。相反,您必须传递回调(或使用承诺)。
惯用的 Meteor 代码应该使用服务器上的 Fibers 来实现 "blocking" 功能。这就是核心 Meteor API 的工作方式,并且在 Meteor 方法中是必需的。您可能会发现 Meteor.wrapAsync
比使用 future
更方便。
在常规 node.js 代码中,您可以使用纤程,但更常见的是使用 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;
});
}