【问题标题】:NodeJS promises with rethinkDBNodeJS 承诺与 rethinkDB
【发布时间】:2018-02-24 18:54:01
【问题描述】:

我在使用 Rethindb 时对 nodeJS 中的 Promise 有疑问。 这段代码将在第一次发生任何变化时给我来自 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);
      })
    });
  });
}

【问题讨论】:

  • 你不能使用这样的承诺。一旦完成,承诺就会解决。您应该改为使用回调函数来处理数据
  • 嗯,所以没有修复或 trix 可以使它工作:P 我现在正在寻求回调解决方案,但我喜欢承诺。然后更好,感觉代码更有条理
  • 你只能解决一次承诺,所以承诺不是你想要的,因为可能会在几分钟内发生多次更改,你可以试试 rxjs,它会给你像订阅这样的方法
  • 会检查一下,谢谢!
  • 我不确定他是否尝试两次解决承诺。每次调用PushData() 时,都会创建一个新的promise,并且它只在resolve(data) 调用上实现,这只会发生一次,并且每次调用PushData() 时都应该触发相应的then() 调用。除非我忽略了一些明显的东西,否则问题可能出在其他地方吗?

标签: node.js rethinkdb rethinkdbdash


【解决方案1】:

是的,您将“承诺”与“回调”混为一谈。 Promise 的一个基本原则是它只能实现一次。解决或拒绝后(两种方式都可以实现),就不能再操作了。

回调并不邪恶。现在是使用它们的时候了。

【讨论】:

    【解决方案2】:

    一个promise 只解析为一个值,并且多次调用resolve() 在一个promise 上每次只会返回那个值。这不是你想要的。

    您想要做的是反复调用cursor.next() 以获取更多的值,一个接一个的承诺。

    不过,您可能还对 ES6 的另一个类似特性感兴趣:Asynchronous Iterator

    这是我将光标从 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)
    }
    

    【讨论】:

      【解决方案3】:

      我的理解是您有一个要调用两次的异步函数。例如,您想向 DB 中插入两行,您将调用该函数两次。

      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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-29
        • 2019-03-19
        • 1970-01-01
        • 2021-08-08
        • 2019-05-15
        • 2020-08-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多