Javascript 承诺结构被误解
我在理解承诺语法方面有问题 所以,我想做的是: getPosts()从数据库获取一些数据,然后,我想通过另一个promise调用,addMetadata()为每一行获取一些元数据。然后,一旦获取了所有的元数据,我就要对其进行处理 请参阅下面我的尝试:Javascript 承诺结构被误解,javascript,promise,Javascript,Promise,我在理解承诺语法方面有问题 所以,我想做的是: getPosts()从数据库获取一些数据,然后,我想通过另一个promise调用,addMetadata()为每一行获取一些元数据。然后,一旦获取了所有的元数据,我就要对其进行处理 请参阅下面我的尝试: var getPosts = function(){ return new Promise(function(resolve, reject){ postModel.find() .exec(functio
var getPosts = function(){
return new Promise(function(resolve, reject){
postModel.find()
.exec(function(err, posts) {
resolve(posts);
);
});
};
var addMetadata = function(posts){
var options = {
host: 'localhost',
port: 3000,
path: '',
method: 'GET'
};
var postPromises = posts.map(function(post) {
return new Promise(function(resolve) {
options.path = '/api/user?id=' + post.profileID;
var req = http.get(options, function(res) {
var bodyChunks = [];
res.on('data', function(chunk) {
bodyChunks.push(chunk);
}).on('end', function() {
var body = Buffer.concat(bodyChunks);
var parsedBody = JSON.parse(body);
post.fullname = parsedBody.user.fullname;
post.profilePic = parsedBody.user.profilePic;
// resolve the promise with the updated post
resolve(post);
});
});
});
});
// Is this the right place to put Promise.all???
Promise.all(postPromises)
.then(function(posts) {
//What should I put here
});
};
getPosts()
.then(function(posts){
return addMetadata(posts);
})
.then(function(posts){//I get a little lost here
console.log();//posts is undefined
});
当然,我的理解是错误的,但我认为我走的是正确的道路。有人能给我指一下正确的方向吗
谢谢如果我没记错的话,你想在这里做的事叫做流,因为你想称多个平行承诺,因为你使用
map
在帖子列表中循环的概念不会这样做
看一下这段介绍streams的短片,他正在使用名为
下面是一个关于流的简短示例
const stupidNumberStream = {
each: (callback) => {
setTimeout( () => callback(1), 3000 )
setTimeout( () => callback(2), 2000 )
setTimeout( () => callback(3), 1000 )
}
}
stupidNumberStream.each(console.log)
如果我没记错的话,你想在这里做的就是称之为流,因为你想称之为多个平行承诺,因为你使用
map
在帖子列表中循环的概念不会以这种方式起作用
看一下这段介绍streams的短片,他正在使用名为
下面是一个关于流的简短示例
const stupidNumberStream = {
each: (callback) => {
setTimeout( () => callback(1), 3000 )
setTimeout( () => callback(2), 2000 )
setTimeout( () => callback(3), 1000 )
}
}
stupidNumberStream.each(console.log)
理解它的异步概念以及内容何时可用的关键点 阅读有助于你找到正确的方向 例如:
var promise = new Promise(function(resolve, reject) {
resolve(1);
});
promise
.then(function(val) {
console.log(val); // 1
return val + 2;
})
.then(function(val) {
console.log(val); // 3
})
根据您的场景,为了让所有元数据都承诺。所有的都是一条路要走
Promise.all(arrayOfPromises).then(function(arrayOfResults) {
// One result per each promise of AddMetadata
})
理解它的异步概念以及内容何时可用的关键点
阅读有助于你找到正确的方向
例如:
var promise = new Promise(function(resolve, reject) {
resolve(1);
});
promise
.then(function(val) {
console.log(val); // 1
return val + 2;
})
.then(function(val) {
console.log(val); // 3
})
根据您的场景,为了让所有元数据都承诺。所有的都是一条路要走
Promise.all(arrayOfPromises).then(function(arrayOfResults) {
// One result per each promise of AddMetadata
})
改变
进入
这样,您的addMetadata
函数将返回Promise
,当postPromises
中的任何一个被拒绝时,该函数将在所有承诺都被解析或拒绝时进行解析。
// Is this the right place to put Promise.all???
Promise.all(postPromises)
.then(function (posts) {
//What should I put here
});
进入
通过这种方式,addMetadata
函数将返回Promise
,当postPromises
中的任何一个被拒绝时,所有承诺都将被解析或拒绝。您的getPosts
函数很好,因为它唯一的工作就是提示数据库查找。(不过,我认为如果是mongo,执行官会给你一个承诺)
您的addMetadatatoPost
不太好,因为它混淆了处理一系列帖子和“提示”http.get。使用在第一个函数中正确应用的相同模式,并返回执行单个get和添加元数据的承诺。(更好的做法是只包装get,您可以重用它,并构建一个简单的add metadata函数,该函数返回承诺,而不是创建承诺)
现在,批处理函数很简单:
// also renamed pedantically
var addMetadataToAllPosts = function(posts){
var postPromises = posts.map(function(post) {
return addMetadataToAPost(post)
})
return Promise.all(postPromises)
};
您的原始代码应该可以工作
getPosts().then(function(posts){
return addMetadataToAllPosts(posts);
})
.then(function(posts){
console.log(posts);//posts should be an array of posts with metadata added
});
您的getPosts
函数很好,因为它唯一的工作就是保证数据库的查找。(不过,我认为如果是mongo,执行官会给你一个承诺)
您的addMetadatatoPost
不太好,因为它混淆了处理一系列帖子和“提示”http.get。使用在第一个函数中正确应用的相同模式,并返回执行单个get和添加元数据的承诺。(更好的做法是只包装get,您可以重用它,并构建一个简单的add metadata函数,该函数返回承诺,而不是创建承诺)
现在,批处理函数很简单:
// also renamed pedantically
var addMetadataToAllPosts = function(posts){
var postPromises = posts.map(function(post) {
return addMetadataToAPost(post)
})
return Promise.all(postPromises)
};
您的原始代码应该可以工作
getPosts().then(function(posts){
return addMetadataToAllPosts(posts);
})
.then(function(posts){
console.log(posts);//posts should be an array of posts with metadata added
});
您能否尝试更好地格式化代码以使其更易于理解?很难说,因为@sp00m指出了格式,但您可能在addMetadataImproved my indentation中缺少返回语句。抱歉@sp00m,terpinmd@BenjaminGruenbaum-这是一篇通用的承诺文章。正如你所看到的,我已经掌握了诀窍,但我找不到哪里出了问题,也找不到哪里出了问题。所有这些都是因为我使用了.then和Promise的组合。所有你能尝试更好地格式化你的代码以使其更容易理解吗?很难说,因为@sp00m指出的格式,但您可能在AddMetadataProfected中缺少返回语句。抱歉@sp00m,terpinmd@BenjaminGruenbaum-这是一篇通用的承诺文章。正如你所看到的,我已经掌握了诀窍,但我找不到哪里出了问题,也找不到哪里出了问题。一切都是因为我使用了。然后和承诺的组合。事实上,这不是我必须走的路线。我只需要一个关于如何构建我的承诺的建议(我得到了这个概念)。正如你所看到的,我就快到了,但我在某个地方搞砸了。刚接触JS也没什么帮助。我写这篇文章的时候,你在那里做了很多修改:-)看第一条评论,他们指出我把这个问题贴得有多糟,哈哈。我简直疯了。谢谢你的建议。我也来看看。你永远不知道这些事情何时会发生是的,这误导了我:)我的坏朋友,对不起,事实上,这不是我必须走的路。我只需要一个关于如何构建我的承诺的建议(我得到了这个概念)。正如你所看到的,我就快到了,但我在某个地方搞砸了。刚接触JS也没什么帮助。我写这篇文章的时候,你在那里做了很多修改:-)看第一条评论,他们指出我把这个问题贴得有多糟,哈哈。我简直疯了。谢谢你的建议。我也来看看。你永远不知道这些事情什么时候会发生是的,这误导了我:)我的坏朋友,对不起,我真的理解这部分,但谢谢你让我记忆犹新。问题在于我的承诺是循环的,我把承诺放在哪里。好吧,那么是的,你必须使用