如何使用promise来避免回调地狱?

这个问题在这里已经有了答案:

  • 不承诺只是回调? 7个答案

  • 试试这个:

    function getPost(id) {
      return Post
        .findOne({id: id})
        .then( post => {
          return post;
        });
    }
    

    使用Q模块

    function getCommentsAndLinks(post) {
      return Q.all([
        Comment.find({id: post.id}),
        Links.find({id: post.id})
      ])
      .done( results => {
        let comments = results[0];
        let links = results[1];
        return [post, comments, links];
      })
      .catch( err => {
      // handle err
      })
    

    在控制器上

    getPost(postId)
    .then(getCommentsAndLinks)
    .then( results => {
      let post = results[0];
      let comments = results[1];
      let links = results[2];
      // more code here
    })
    .catch( err => {
    // handle err
    }) 
    

    但我建议你不要保存IDS字符串,保存对象的实例,这样你就可以使用填充来获取所有的注释和链接数据,如下所示:

    Post
    .findOne({id: id})
    .populate('comments')
    .populate('links')
    .then( post => {
        // here have the post with data of comments and links
    });
    

    你在嵌套回调。 你不需要这样做。 如果你从.then返回一个承诺.then那么任何。然后.then当这个承诺得到解决时.then你链接它将得到解决:

    promise.then(post => Comments.find({id: post.id})
      .then(comments => Links.find({id: post.id})
      .then(links => {});
    

    注释查询不依赖于链接,因此您可以一次执行两个查询:

    promise.then(post => {
      return Promise.all([
         post,
         Comments.find({id: post.id}),
         Links.find({id: post.id}),
      ]);
    }).then(data => res.json({
      post: data[0],
      comments: data[1],
      links: data[2],
    });
    

    如果你使用蓝鸟这样的库,你也可以使用类似spread操作符的名称来使名称更加透明。


    我还会考虑使用co来生成基于生成器的控制流,因为我认为这更清晰:

    co(function* () {
      const post = yield Posts.findOne({id});
      const [comments, links] = yield [
        Comments.find({id: post.id}),
        Links.find({id: post.id}),
      ];
    
      res.json({post, comments, links});
    });
    

    使用promise的好处是你可以链接它们,所以你的代码可以简化为:

    let post, comments;
    Posts.findOne({id: id}).exec().then(_post => {
        post = _post;
        return Comments.find({id: post.id}).exec();
      }).then(_comments => {
        comments = _comments;
        return Links.find({id: post.id}).exec();
      }).then(links => res.json({post, comment, links}))
      .catch(error => res.error(error.message));
    

    你会注意到我只需要一个catch块。

    链接地址: http://www.djcxy.com/p/55439.html

    上一篇: How to use promise to avoid callback hell?

    下一篇: What is the difference between callback and promise