gpt4 book ai didi

javascript - 异步/等待操作发生在预期的顺序之外

转载 作者:行者123 更新时间:2023-11-30 08:23:59 25 4
gpt4 key购买 nike

我正在尝试根据 IMDB 结果更新数据库中的一堆记录,供一个学习 Node 和 React 的爱好网站使用。我对 async/await 代码和 promises 还很陌生,所以我很吃力。

根据我所阅读的内容,这段代码应该:

  • 从我的数据库中检索我所有的“TopMovies”记录
  • 等待所有记录完成后再继续
  • 异步调用处理以更新来自 IMDB 的每条记录上的一些基本字段
  • 将每个单独的记录保存为它的异步线程的一部分
  • 返回所有处理过的记录

相反,我得到以下控制台信息:

[0] Executing (default): SELECT `id`, `rank`, `name`, `IMDBId`, `rating`, `genre`, `posterUrl`, `createdAt`, `updatedAt`, `reviewerId`, `yearId` FROM `TopMovies` AS `TopMovie`;
[0] Movie count: 150
[0] All done
[0] Updated movie: Chef
[0] Executing (default): UPDATE `TopMovies` SET `rating`=3.5,`genre`='Adventure',`posterUrl`='https://images-na.ssl-images-amazon.com/images/M/MV5BMTY5NTYzNTA1M15BMl5BanBnXkFtZTgwODIwODU1MTE@._V1_UY268_CR0,0,182,268_AL_.jpg',`updatedAt`='2018-02-02 19:49:17.036 +00:00' WHERE `id` = 44
[0] Updated movie: The Champions
[0] Executing (default): UPDATE `TopMovies` SET `rating`=4.5,`genre`='10 October 2015 (USA) ',`posterUrl`='https://images-na.ssl-images-amazon.com/images/M/MV5BMTk5MjM2MjQ4MF5BMl5BanBnXkFtZTgwNjIxMDA5NzE@._V1_UX182_CR0,0,182,268_AL_.jpg',`updatedAt`='2018-02-02 19:49:17.092 +00:00' WHERE `id` = 87
[0] Updated movie: Trance

请注意,它在输出“全部完成”并从 app.get() 函数返回后更新记录。理想情况下,它会更像:

[0] Executing (default): SELECT `id`, `rank`, `name`, `IMDBId`, `rating`, `genre`, `posterUrl`, `createdAt`, `updatedAt`, `reviewerId`, `yearId` FROM `TopMovies` AS `TopMovie`;
[0] Movie count: 150
[0] Updated movie: Chef
[0] Executing (default): UPDATE `TopMovies` SET `rating`=3.5,`genre`='Adventure',`posterUrl`='https://images-na.ssl-images-amazon.com/images/M/MV5BMTY5NTYzNTA1M15BMl5BanBnXkFtZTgwODIwODU1MTE@._V1_UY268_CR0,0,182,268_AL_.jpg',`updatedAt`='2018-02-02 19:49:17.036 +00:00' WHERE `id` = 44
[0] Updated movie: The Champions
[0] Executing (default): UPDATE `TopMovies` SET `rating`=4.5,`genre`='10 October 2015 (USA) ',`posterUrl`='https://images-na.ssl-images-amazon.com/images/M/MV5BMTk5MjM2MjQ4MF5BMl5BanBnXkFtZTgwNjIxMDA5NzE@._V1_UX182_CR0,0,182,268_AL_.jpg',`updatedAt`='2018-02-02 19:49:17.092 +00:00' WHERE `id` = 87
[0] Updated movie: Trance
[0] All done
* Returns from app.get

我做错了什么,让它在处理任何记录之前说“全部完成”?相关代码如下:

const imdb = require('imdb');
const _require = require('./models/index'),
Year = _require.Year,
Reviewer = _require.Reviewer,
TopMovie = _require.TopMovie,
ViewStat = _require.ViewStat,
Op = _require.Sequelize.Op;

app.get('/imdb_import', (req, res) => {
const UpdateMovies = async () => {
const topMovies = await TopMovie.findAll();
console.log("Movie count: " + _.size(topMovies));

// await topMovies.forEach(async topMovie => {
// await updateMovieDetails(topMovie);
// });
await Promise.all(topMovies.map(async(topMovie) => {
await updateMovieDetails(topMovie);
}));

console.log("All done");
return topMovies;
};

const updateMovieDetails = topMovie => {
return imdb(topMovie.get('IMDBId'), (err, data) => {
if (err) {
console.log(err.stack);
}
if (data) {
topMovie.posterUrl = data.poster;
topMovie.rating = Math.round(data.rating) / 2;
if (data.genre) {
topMovie.genre = data.genre[0];
}
topMovie.save();
console.log("Updated movie: " + topMovie.name);
}
});
};

UpdateMovies()
.then((data) => res.status(200).json(data))
.catch(error => console.log(error));
});

可以在此处的“async_imdb”分支中找到此项目的代码:https://github.com/mandreko/ov_stats/tree/async_imdb如果有人想在本地运行它

最佳答案

await updateMovieDetails(topMovie); 在此代码中没有完成任何事情。请记住,await 不会阻止包含函数完成并返回一个 promise 。它只影响函数内的代码。

因此,如果您希望使用它来对您的操作进行排序,它不会那样做。此外,因为您没有从 .map() 回调中返回任何内容,所以 updateMovieDetails(topMovie) 的 promise 不会返回到 Promise.all() 所以它不在等待他们。

改变这个:

await Promise.all(topMovies.map(async(topMovie) => {
await updateMovieDetails(topMovie);
}));

为此:

await Promise.all(topMovies.map((topMovie) => {
return updateMovieDetails(topMovie);
}));

然后 Promise.all() 将等待所有 updateMovieDetails() 调用完成。

此外,updateMovieDetails() 不会返回与其事件相关联的 promise ,因此对这些执行 Promise.all() 不会完成任何事情。

您可以手动对 imbdb() 函数进行 promise ,然后像这样返回由此产生的 promise :

const util = require('util');
// make promsified version of imdb()
const imdbPromise = util.promisify(imdb);

const updateMovieDetails = topMovie => {
return imdbPromise(topMovie.get('IMDBId')).then(data => {
if (data) {
topMovie.posterUrl = data.poster;
topMovie.rating = Math.round(data.rating) / 2;
if (data.genre) {
topMovie.genre = data.genre[0];
}
console.log("Updated movie: " + topMovie.name);
topMovie.save();
}
});
};

以下是我推荐的内容的积累:

const util = require('util');
// make promsified version of imdb()
const imdbPromise = util.promisify(imdb);

app.get('/imdb_import', (req, res) => {
const UpdateMovies = async () => {
const topMovies = await TopMovie.findAll();
console.log("Movie count: " + _.size(topMovies));

await Promise.all(topMovies.map(updateMovieDetails);

console.log("All done");
return topMovies;
};

const updateMovieDetails = topMovie => {
return imdbPromise(topMovie.get('IMDBId')).then(data => {
if (data) {
topMovie.posterUrl = data.poster;
topMovie.rating = Math.round(data.rating) / 2;
if (data.genre) {
topMovie.genre = data.genre[0];
}
console.log("Updated movie: " + topMovie.name);
return topMovie.save();
}
});
};

UpdateMovies()
.then((data) => res.status(200).json(data))
.catch(error => console.log(error));
});

关于javascript - 异步/等待操作发生在预期的顺序之外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48589980/

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