Javascript Promise - 第二个然后在第一个之前运行

Javascript Promise - Second then runs before first one

我创建了一个简单的脚本来获取 Strava 活动并将它们保存到 mongoDB,但是我 运行 遇到了以下问题:

在获取和提交活动之前,我的数据库连接断开了。以下代码输出:

const stravaApi = require('strava-v3');
const mongoose = require('mongoose');
const Activity = require('./models/Activity');

mongoose.connect(process.env.DB_CONNECTION, () => console.log('connected to DB'))

strava = new stravaApi.client(accessToken)
strava.athlete.listActivities({per_page: 2})
        .then(payload => {
            let activities = []
            for (let strava_activity of payload) {
                const activity = new Activity({
                        activityId: strava_activity['id'],
                        name: strava_activity['name'],
                        date: strava_activity['start_date'],
                        type: strava_activity['type'],
                        distance: strava_activity['distance']
                })
                activity.save()
                    .then(data => {
                        console.log(`Activity from date ${strava_activity['start_date']} saved to DB`);
                     })
                    .catch(err => {
                        console.log(err)
                    })
            }
        })
        .then(() => {
            console.log('Start disconnect')
            mongoose.disconnect().then(() => {
                console.log("DB disconnected successfully")
            })
        })
        .catch(err => {
            console.log(err)
        })

输出

connected to DB
DB disconnected successfully
(Error message)
(Error message)

尝试仅在所有 promise 实例结束时通过 DB disconnect,如下所示:

strava.athlete.listActivities({per_page: 2})
    .then(payload => {
        let activities = []
        for (let strava_activity of payload) {
            const activity = new Activity({
                    activityId: strava_activity['id'],
                    name: strava_activity['name'],
                    date: strava_activity['start_date'],
                    type: strava_activity['type'],
                    distance: strava_activity['distance']
            })
            activity.save()
                .then(data => {
                    console.log(`Activity from date ${strava_activity['start_date']} saved to DB`);
                 })
                .catch(err => {
                    console.log(err)
                })
        }
    })
    .then(() => {})
    .catch(err => {
        console.log(err)
    }).finally(() => {
        console.log('Start disconnect')
        mongoose.disconnect().then(() => {
            console.log("DB disconnected successfully")
        })
    })

这样他们只有在咨询结束后才会断开连接

for 循环运行的 then-回调不是 return 承诺,因此链接到它的 then- 回调将开始下一个微任务。

for 循环中的承诺应该建立在 then-回调将 return 的承诺之上,而不是由 [=] 编辑的承诺 return 16=] 被忽略。

当您使用 async await 语法时,事情会变得更容易:

(async function () {
    await mongoose.connect(process.env.DB_CONNECTION);
    console.log('connected to DB');

    const strava = new stravaApi.client(accessToken);
    const payload = await strava.athlete.listActivities({per_page: 2});
    for (const {id, name, start_date, type, distance} of payload) {
        const activity = new Activity({
            activityId: id,
            name,
            date: start_date,
            type,
            distance
        });
        await activity.save();
        console.log(`Activity from date ${start_date} saved to DB`);
    }
    console.log('Start disconnect')
    await mongoose.disconnect();
    console.log("DB disconnected successfully");
})().catch(console.log);