admin管理员组文章数量:1429067
I have a function that fetches data from a database:
recentItems = function () {
Items.find({item_published: true}).exec(function(err,item){
if(!err)
return item
});
};
And I want to use it like this:
var x = recentItems();
But this fails with undefined value due to Async behavior of recentItems
. I know that I can change my function to use a callback like this:
recentItems = function (callback) {
Items.find({item_published: true}).exec(function(err,item){
if(!err)
callback(item)
});
};
And:
recentItems(function(result){
var x = result;
});
But i dont want to use this method because i have a situation like this. i have a function that should do two operations and pus result to an array and after them, fire a callback and return value:
var calc = function(callback){
var arr = [];
var b = getValues();
arr.push(b);
recentItems(function(result){
var x = result;
arr.push(x);
});
callback(arr);
};
In this situation, the value of b
pushed to arr
and the main callback called and after that value of x
fetched from recentItems
duo to Async behavior of recentItems
. But I need this two operation runs sequentially and one after one. After calculating all of them, then last line runs and the callback fired.
How can I resolve this? I read about the Promises
and Async
libraries, but I don't know which of them is my answer. Can I overe this with raw Node.js? If so, I would prefer that.
I have a function that fetches data from a database:
recentItems = function () {
Items.find({item_published: true}).exec(function(err,item){
if(!err)
return item
});
};
And I want to use it like this:
var x = recentItems();
But this fails with undefined value due to Async behavior of recentItems
. I know that I can change my function to use a callback like this:
recentItems = function (callback) {
Items.find({item_published: true}).exec(function(err,item){
if(!err)
callback(item)
});
};
And:
recentItems(function(result){
var x = result;
});
But i dont want to use this method because i have a situation like this. i have a function that should do two operations and pus result to an array and after them, fire a callback and return value:
var calc = function(callback){
var arr = [];
var b = getValues();
arr.push(b);
recentItems(function(result){
var x = result;
arr.push(x);
});
callback(arr);
};
In this situation, the value of b
pushed to arr
and the main callback called and after that value of x
fetched from recentItems
duo to Async behavior of recentItems
. But I need this two operation runs sequentially and one after one. After calculating all of them, then last line runs and the callback fired.
How can I resolve this? I read about the Promises
and Async
libraries, but I don't know which of them is my answer. Can I overe this with raw Node.js? If so, I would prefer that.
- 1 This is probably one of the most popular duplicate questions about node.js. Your operation is ASYNC. You cannot return the result from a synchronous function because the async results happens sometime in the future. If you want to chain multiple operations, then either nest your callbacks or use promises or use the async library. – jfriend00 Commented Sep 21, 2015 at 3:27
- 1 I gave you three choices in my ment. FYI, promises are built into node.js so they are "raw node.js" now and highly remended. – jfriend00 Commented Sep 21, 2015 at 3:30
- 1 @Fcoder: If you are new to async code then the proper way to overe it is to not overe it. You already know how to handle it so just do it. Once you have a bit more experience take a look at promises. Note that promises don't remove the need for callbacks, they just restructure your callbacks to remove nesting. So before learning about promises get fortable with regular callbacks first. – slebetman Commented Sep 21, 2015 at 3:34
-
2
I don't agree with the
duplicate
flag, since NodeJS 4.0.0 is very new, and there are new ways of doing what the OP wants today. – Buzinas Commented Sep 21, 2015 at 3:38 - 1 A bunch of questions with examples of sequencing async operations: stackoverflow./questions/32028552/…, stackoverflow./questions/29880715/…, stackoverflow./questions/29454785/async-js-and-series-issue/…, stackoverflow./a/29906506/816620 – jfriend00 Commented Sep 21, 2015 at 3:46
3 Answers
Reset to default 3There are some ways of doing what you want, but none of them are ~perfect~ yet.
There is an ES7 proposal of native async/await
that will be the callback heaven, but atm, you can do:
- Nested callbacks (native, but very ugly and unmaintainable code)
- Promises (good, but still too verbose)
- Async/Await library (It's an amazing library, but very far from native, and performance isn't cool)
- ES7 transpiler - you can write the ES7 code today, and it will transpile for you to ES5 (e.g Babel)
But, if you're already using the newest version of NodeJS (4.0.0 as the time of writing) - and if you're not, you really should - the best way of achieving what you want is to use generators.
Combined with a small library named co, it will help you to achieve almost what the ES7 async/await
proposes, and it will mostly use native code, so both readability and performance are really good:
var co = require('co');
var calc = co(function *calc() {
var arr = [];
var b = getValues();
arr.push(b);
var items = yield recentItems();
arr.push(items);
return arr;
});
function recentItems() {
return new Promise(function(resolve) {
Items.find({item_published: true}).exec(function(err, item) {
if(!err)
resolve(item);
});
}
You can read more about this subject in this awesome Thomas Hunter's blog post.
You've almost got it. There is no method to work-around callbacks. However, you can certainly use callbacks to do what you want. Simply nest them:
var calc = function(callback){
var arr = [];
getValues(function(b){
arr.push(b);
recentItems(function(result){
var x = result;
arr.push(x);
callback(arr);
});
});
};
You can try something like this. It still nests the callbacks, but the code is a little cleaner.
var callA = function(callback) {
//Run the first call
prompt(callback(data));
}
var callB = function(callback) {
//Some other call
prompt(callback(data));
}
callA(function(dataA) {
callB(function(dataB) {
//Place a handler function here
console.log(dataA + " " + dataB)
})
});
本文标签: javascriptRunning code sequentially in NodejsStack Overflow
版权声明:本文标题:javascript - Running code sequentially in Node.js - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745524070a2661755.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论