最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

完全失去了承诺异步等待

运维笔记admin11浏览0评论

完全失去了承诺异步/等待

完全失去了承诺异步/等待

我正在尝试在NodeJS 11.6.x上开发一个相对简单的测试。我不是真正的开发人员,但有时会尝试编写代码。

我的目标是创建一个SQLite数据库,并在每次运行代码时重复一些步骤:1。删除表(如果存在)2。创建表3.插入N行4.计算数据库中的行数.5。关闭数据库

我首先尝试使用回调的基本方法,但无法找到一种方法来制作第3步(插入N行)并寻找解决方案,承诺async / await'模式'听起来完成了一切。

但是,在重构代码之后,步骤1(删除表)没有运行,我仍然无法执行步骤3(插入N行)并且不知道发生了什么。我也尝试使用承诺包,没有运气。

有人可以请一看并帮忙,如果可能的话,解释一下或给出一些建议吗?

提前致谢

编辑:好吧,我不习惯在这里发帖,并且不知道在这里更新事情的“正确”方式。我beleave我应该留下第一个代码作为参考,买我没有了。现在我觉得我在那里。所有步骤都按顺序执行。只是步骤3(插入N行),我无法使其工作。或者它插入并停止不进入下一个'.then'或它只是插入1行,我无法想象正在发生的事情。在代码中,我用“BUG 1:”和“BUG 2:”两行注释。

  1. 如果我都被评论,我得到了正在发生的事情,它只插入1行,不继续承诺链
  2. 如果我评论BUG 1并让BUG 2激活,它只插入一行并继续。我想我理解为什么
  3. 如果我评论BUG 2并让BUG 1激活,它会插入所有行但不再继续,我想我理解为什么
  4. 如果我取消注释两者(我认为应该工作的方式。不工作,并返回一个附加错误“分段错误”

代码:

const sqlite3 = require('sqlite3')

let db = new sqlite3.Database('./test.db');

waitTime = 1

process.stdout.write('Starting...\n')
var test = new Promise((resolve, reject) => {
    process.stdout.write('Drop Table... ');
    db.run(`DROP TABLE IF EXISTS test`, (err) => {
        if (err) {
            process.stdout.write(`Dropping Error ${err.message}\n`)
            reject()
        } else {
            setTimeout(() => {
                process.stdout.write(`Dropped!\n`)
                resolve()
            }, waitTime)
        }
    })
})
test.then(() => {
    return new Promise((resolve, reject) => {
        process.stdout.write('Create Table... ')
        db.run(`CREATE TABLE IF NOT EXISTS test (data TEXT)`, (err) => {
            if (err) {
                process.stdout.write(`Creating Error ${err.message}\n`)
                reject()
            } else {
                setTimeout(() => {
                    process.stdout.write(`Created!\n`)
                    resolve()
                }, waitTime)
            }
        })
    })
}).then(() => {
    return new Promise((resolve, reject) => {
        process.stdout.write('Insert Line... ')
        lines = 10
        let loop = (async () => {
            for (let i = 0; i < lines; i++) {
                await new Promise(resolve =>
                    db.run(`INSERT INTO test (data) VALUES ('a')`, (err) => {
                        if (err) {
                            process.stdout.write(`Inserting Error ${err.message}\n`)
                            throw (err)
                        } else {
                            setTimeout(() => {
                                // process.stdout.write(`Line ${i} Inserted!\n`)
                                process.stdout.write(`, ${i+1}`)
                                resolve() // BUG 1: if this line is commented, comment it, it will insert only 1 line
                            }, waitTime)
                        }
                    })
                )
            }
        })()
        process.stdout.write(`, IDone\n`)
        resolve() // BUG 2: If this line is commented, the promise chain stops here
    })
}).then(() => {
    return new Promise((resolve, reject) => {
        process.stdout.write('Count Line(s)... ')
        db.all(`SELECT COUNT(*) AS totalLines FROM test`, [], (err, rows) => {
            if (err) {
                process.stdout.write(`Count Error ${err.message}\n`)
                reject()
            } else {
                setTimeout(() => {
                    process.stdout.write(` ${rows[0].totalLines} Count!\n`)
                    resolve()
                }, waitTime)
            }
        })
    })
}).then(() => {
    return new Promise((resolve, reject) => {
        process.stdout.write('Select Line(s)... ')
        db.all('SELECT data FROM test', [], (err, rows) => {
            if (err) {
                process.stdout.write(`Select Error ${err.message}\n`)
                reject()
            } else {
                rows.forEach((row) => {
                    console.log(row.data);
                })
                setTimeout(() => {
                    process.stdout.write(`${rows[0].totalLines} Select!\n`)
                    resolve()
                }, waitTime)
            }
        })
    })
}).then(() => {
    return new Promise((resolve, reject) => {
        process.stdout.write('Close DB... ')
        db.close((err) => {
            if (err) {
                process.stdout.write(`Closing Error ${err.message}\n`)
                reject()
            } else {
                setTimeout(() => {
                    process.stdout.write(`Closed!\n`)
                    resolve()
                }, waitTime)
            }
        })
    })
}).then(() => {
    console.log('Finished')
})

在@CertainPerformance的非常好的解释之后(非常感谢),我能够让它运行起来。我相信它现在是“正确”的方式。可能有一些更好的方法,但就目前而言,对我而言,最后的代码如下:

const sqlite3 = require('sqlite3')

let db = new sqlite3.Database('./test.db');

lines = 10

process.stdout.write('Starting... ')
var test = new Promise((resolve, reject) => { process.stdout.write(`Promise Created...!\n`)
        resolve()
})
test.then(() => { process.stdout.write('Drop Table... ')
    return new Promise((resolve, reject) => {
        db.run(`DROP TABLE IF EXISTS test`, (err) => {
            if (err) {
                reject(err)
            } else { process.stdout.write(`Dropped!\n`)
                resolve() }
        })
    })
}).then(() => { process.stdout.write('Create Table... ')
    return new Promise((resolve, reject) => {
        db.run(`CREATE TABLE IF NOT EXISTS test (data TEXT)`, (err) => {
            if (err) {
                reject(err)
            } else {
                process.stdout.write(`Created!\n`)
                resolve() }
        })
    })
}).then(() => { process.stdout.write('Insert Line... ')
    let insertLoop = (async () => {
        for (let i = 0; i < lines; i++) {
            await new Promise(resolve =>
                db.run(`INSERT INTO test (data) VALUES ('a')`, (err) => {
                    if (err) {
                        reject(err)
                    } else { ( i == 0 ) ? process.stdout.write(`${i + 1}`) : process.stdout.write(`, ${i + 1}`)
                        resolve() }
                })
            )
        }
        process.stdout.write(`, Inserted!\n`)
    })()
    return insertLoop
}).then(() => { process.stdout.write('Count Line(s)... ')
    return new Promise((resolve, reject) => {
        db.all(`SELECT COUNT(*) AS totalLines FROM test`, [], (err, rows) => {
            if (err) {
                reject(err)
            } else { process.stdout.write(` ${rows[0].totalLines} Counted!\n`)
                resolve()
            }
        })
    })
}).then(() => { process.stdout.write('Close DB... ')
    return new Promise((resolve, reject) => {
        db.close((err) => {
            if (err) {
                reject(err)
            } else { process.stdout.write(`Closed!\n`)
                resolve()
            }
        })
    })
}).then(() => {
    console.log('Finished')
}).catch((err) => {
    process.stdout.write(`The process did not finish successfully: ${err}`)
})
回答如下:

有两个主要问题。首先,在第二个.then中,你将loop声明为一个立即调用的async函数:这意味着loop将解析为Promise。修剪后的代码如下所示:

}).then(() => {
    return new Promise((resolve, reject) => {
        let loop = (async () => {
            // do some asynchronus stuff
        })()
        resolve() // BUG 2
    })
}).then(() => {

单独声明Promise不会导致当前线程等待它。由于此代码立即打印after,上述代码无法正常工作:

console.log('start');
const prom = new Promise((resolve) => {
  setTimeout(resolve, 500);
});
console.log('after');

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论