Javascript 承诺结构被误解

Javascript 承诺结构被误解,javascript,promise,Javascript,Promise,我在理解承诺语法方面有问题 所以,我想做的是: getPosts()从数据库获取一些数据,然后,我想通过另一个promise调用,addMetadata()为每一行获取一些元数据。然后,一旦获取了所有的元数据,我就要对其进行处理 请参阅下面我的尝试: var getPosts = function(){ return new Promise(function(resolve, reject){ postModel.find() .exec(functio

我在理解承诺语法方面有问题

所以,我想做的是:

getPosts()从数据库获取一些数据,然后,我想通过另一个promise调用,addMetadata()为每一行获取一些元数据。然后,一旦获取了所有的元数据,我就要对其进行处理

请参阅下面我的尝试:

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也没什么帮助。我写这篇文章的时候,你在那里做了很多修改:-)看第一条评论,他们指出我把这个问题贴得有多糟,哈哈。我简直疯了。谢谢你的建议。我也来看看。你永远不知道这些事情什么时候会发生是的,这误导了我:)我的坏朋友,对不起,我真的理解这部分,但谢谢你让我记忆犹新。问题在于我的承诺是循环的,我把承诺放在哪里。好吧,那么是的,你必须使用