Javascript 在Promise中传递变量

Javascript 在Promise中传递变量,javascript,promise,Javascript,Promise,我在我的应用程序中使用promise mysql,我需要查询一本书的信息,然后检索与它的作者相同的一些书 代码: return Promise.all([ pool.query(sql, id), ]).then(data=> { var book = data[0][0]; if (book.author) { var authorSql = "select * from authors where name = ? limit 10";

我在我的应用程序中使用promise mysql,我需要查询一本书的信息,然后检索与它的作者相同的一些书

代码:

return Promise.all([
    pool.query(sql, id),
]).then(data=> {
    var book = data[0][0];
    if (book.author) {
        var authorSql = "select * from authors where name = ? limit 10";
        return pool.query(authorSql, book.author);
    } else {
        return Promise.resolve(book);
    }

}).then(object=> {
    if (object.id) {
        // this is a book instance, return it back
        return object
    } else {
        // this should an array of books
        var booksWithSameAuthor = object;
        // but how to get the origin book here, something like:

        var book = xxxx
        book.recommends_by_author = booksWithSameAuthor
        return book
    }
});
如图所示,在第二个
then
函数中,
object
可能是
book
对象或类似数组的查询数据行,在后面的情况下,我也需要
book
对象,但我不知道如何传递它


有什么想法吗?

如果需要通过承诺链向下传递多个值,可以传递一个对象,而不是单个值

return {
    book: book,
    somethingElse: obj
};
在下一个
.then()
函数中,您可以检索它:

.then(data => {
    console.log(data.book);
    console.log(data.somethingElse);
})

您可以将第二个pool.query与.then链接,然后更改book对象

...
  return pool.query(authorSql, book.author).then(authors => {
    book.authorList = authors;
    return Promise.resolve(book);
  });
...

然后,您可以检查是否在final.Then()中设置了book.authorList。

整个代码段可以更改为

return Promise.all([
    pool.query(sql, id),
])
.then(data=> {
    var book = data[0][0];
    if (book.author) {
        var authorSql = "select * from authors where name = ? limit 10";
        return pool.query(authorSql, book.author)
        .then(object=>{
            book.recommends_by_author = object;
            return book;
        });
    } else {
        return book;
    }
});
你使用嵌套的。然后(是的,我知道,你想避免金字塔)-在嵌套中。然后你在书上设置
recomments\u by\u author
属性


注意,在.then中,不需要返回
Promise.resolve(book)
,因为.then“默认”返回一个Promise,因此,
return book
在“main”中都足够了。然后在内部
。然后

注意
对象这个词,它是javascript(和许多其他语言)中的一个关键字这就是为什么它会以蓝色突出显示的原因。我建议使用另一种变体,如
obj
object
是关键字吗?我不这么认为。
返回pool.query(authorSql,book.author)。然后(authors=>({authors,book}))-然后
booksWithSameAuther=object.authors,book=object.book
@Soviut
object
不是关键字(甚至
object
也不是关键字),更改它(而不是
obj
)的原因是因为它毫无意义。如何返回承诺(How is
return Promise.resolve(book))中提供了一系列解决此问题的通用解决方案
这里不同于仅仅
返回书籍
?@torazburo的区别在于,返回的承诺只有在第二次查询完成后才能完成,并且authorList被添加到book对象中。您只需要
返回书籍
,而不需要
承诺。解析(书籍)
,在codeNo的片段中。在语义上,它们完全相同。我知道你只是从OP的代码中获取了这个,但是修复它还是很好的。如果
也阻止了金字塔,你也不会调用嵌套的
,是吗-D这是正确的解决方案,+1。如果你需要缩进代码,你做得不对:p-我可能使用了错误的术语,你知道,第n级回调中的回调,这是承诺应该“修复”的:老实说,我不会让
else
放在
返回书
-但那只是我的
中的缩进代码,如果
块为可读性:-)承诺只能展平线性链,而不是分支链-你需要分别展平每个分支。只有
async
/
await
才能“修复”这个问题。@Bergi-我还没有完全了解async/await-我可以看出它的吸引力,但(个人)还没有发现它在现实世界中的用途-此外,从专业角度来说,我还必须与支持IE11抗争-不确定在那只恐龙身上是否有一种“模仿”async/await的简单方法