NodeJS обещает переосмыслить
У меня есть вопрос, касающийся обещаний в nodeJS при использовании Rethindb. Этот код даст мне результаты из db в первый раз, когда что-то изменится, не более.
Допустим, я запускаю скрипт и добавляю строку в базу данных, новые данные будут напечатаны в cmd. Но если я добавлю еще один, ничего не отображается. Что-то не так с тем, как я использую обещание? (и нет, я не хочу использовать обратный вызов)
Спасибо!
PushData(r, table)
.then(res=>{
console.log(res);
}
function PushData(r, table){
return new Promise(function(resolve, reject){
r.table(table)
.changes()
.run()
.then(function(cursor){
cursor.on("error", function(err) {
reject(err)
})
cursor.on("data", function(data) {
resolve(data);
})
});
});
}
2 ответа
Да, вы связываете "обещания" с "обратными вызовами". Основополагающий принцип Обещания заключается в том, что его можно выполнить ТОЛЬКО ОДИН РАЗ. После того, как он был разрешен или отклонен (двумя способами это может быть выполнено), он не может быть снова запущен.
Обратные вызовы не являются злом. Это время, чтобы использовать их.
Насколько я понимаю, у вас есть асинхронная функция, которую вы хотите вызвать дважды. например, вы хотите вставить две строки в БД, вы вызовете функцию дважды.
const PushData = async (r, table) => {
try {
const res = await new Promise(function (resolve, reject) {
r.table(table)
.changes()
.run()
.then(function (cursor) {
cursor.on("error", function (err) {
reject(err)
})
cursor.on("data", function (data) {
resolve(data);
})
});
});
return res
} catch (error) {
throw error
}
}
var res1 = await PushData(r,table)
console.log("result 1 is ==> "+res1)
var res2 = await PushData(r,table)
console.log("result 2 is ==> "+res2)
Обещание сводится только к одному значению и вызывает resolve()
несколько раз в обещании только возвращают это значение каждый раз. Это не то, что вы хотите.
Вместо этого вы хотите повторно позвонить cursor.next()
чтобы получить больше ценностей, одно обещание за другим.
Тем не менее, вас также может заинтересовать другая похожая функция ES6: асинхронный итератор.
Вот мой код для преобразования курсора из rethinkdb в асинхронный итератор:
import { $$asyncIterator } from 'iterall'
// Transform the cursor's stream into an Async Iterator.
function feedToAsyncIterator (p) {
return {
next () {
return p.then(async cursor => {
try {
// See https://www.rethinkdb.com/api/javascript/next/
const row = await cursor.next()
return {value: row, done: false}
}
catch (e) {
return {done: true}
}
})
},
[$$asyncIterator]() {
return this
}
}
}
const myChangeFeed = r.table('myTable').changes().run(db)
// You can enumerate the changes from inside an async function this way:
for await (const change of feedToAsyncIterator(myChangeFeed)) {
console.log('change:', change)
}