gpt4 book ai didi

javascript - 在 JavaScript promise 中思考(在本例中为 Bluebird)

转载 作者:IT老高 更新时间:2023-10-28 23:10:58 24 4
gpt4 key购买 nike

我试图了解一些不太重要的 promise /异步用例。在我目前正在处理的一个示例中,我有一个从 knex 查询(thenable 数组)返回的书籍数组,我希望将其插入数据库:

books.map(function(book) {

// Insert into DB

});

每本书的外观如下:

var book = {
title: 'Book title',
author: 'Author name'
};

但是,在我插入每本书之前,我需要从一个单独的表中检索作者的 ID,因为这些数据是标准化的。作者可能存在也可能不存在,所以我需要:

  • 检查作者是否存在于数据库中
  • 如果是,请使用此 ID
  • 否则,插入作者并使用新 ID

不过,上面的操作也都是异步的。

我可以在原始映射(获取和/或插入 ID)中使用 promise 作为插入操作的先决条件。但这里的问题是,因为一切都是异步运行的,所以代码很可能会插入重复的作者,因为初始的 check-if-author-exists 与 insert-a-new-author block 是分离的。

我可以想出几种方法来实现上述目标,但它们都涉及拆分 promise 链,而且通常看起来有点困惑。这似乎是必须经常出现的问题。我确定我在这里遗漏了一些基本的东西!

有什么建议吗?

最佳答案

假设您可以并行处理每本书。那么一切都很简单(仅使用 ES6 API):

Promise
.all(books.map(book => {
return getAuthor(book.author)
.catch(createAuthor.bind(null, book.author));
.then(author => Object.assign(book, { author: author.id }))
.then(saveBook);
}))
.then(() => console.log('All done'))

问题在于获取作者和创建新作者之间存在竞争条件。考虑以下事件顺序:

  • 我们尝试为 B 书找到作者 A;
  • 获取作者 A 失败;
  • 我们请求创建作者A,但尚未创建;
  • 我们尝试为 C 书找到作者 A;
  • 获取作者 A 失败;
  • 我们要求创建作者 A(再次!);
  • 第一个请求完成;
  • 第二个请求完成;

现在我们在作者表中有两个 A 实例。这是不好的!为了解决这个问题,我们可以使用传统的方法:锁定。我们需要保留每个作者锁的表。当我们发送创建请求时,我们锁定了相应的锁。请求完成后,我们将其解锁。其他所有涉及同一作者的操作都需要先获取锁才能做任何事情。

这似乎很难,但在我们的例子中可以简化很多,因为我们可以使用我们的请求 promise 而不是锁:

const authorPromises = {};

function getAuthor(authorName) {

if (authorPromises[authorName]) {
return authorPromises[authorName];
}

const promise = getAuthorFromDatabase(authorName)
.catch(createAuthor.bind(null, authorName))
.then(author => {
delete authorPromises[authorName];
return author;
});

authorPromises[author] = promise;

return promise;
}

Promise
.all(books.map(book => {
return getAuthor(book.author)
.then(author => Object.assign(book, { author: author.id }))
.then(saveBook);
}))
.then(() => console.log('All done'))

就是这样!现在,如果对作者的请求正在进行中,则将返回相同的 promise 。

关于javascript - 在 JavaScript promise 中思考(在本例中为 Bluebird),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30193311/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com