【问题标题】:How to access promise passed back through a function?如何访问通过函数传回的承诺?
【发布时间】:2020-02-07 10:44:30
【问题描述】:

我对 javascript 的 Promise 不熟悉,因此感谢您的帮助。我的代码尝试从 firebase 访问数据库并将函数中的列表从 main_page.js 传递给 index.js。我正在以承诺的形式取回我的结果,但我很难访问其中的值。

ma​​in_page.js:UniqueCourse 函数,用于从 firebase 检索课程。返回课程列表

    // Get Unique Course ID
    function UniqueCourse(t_id){
      var courseArray = []
      return Promise.resolve(
        firebase.database().ref('/users').once('value',

        function(snapshot) {
          details = snapshot.val()
          //console.log(snapshot.val());

         for (var key in details) {
            if (details.hasOwnProperty(key)) {
              //console.log(key + " , " + details[key].username + "\n");
              if (details[key].username == t_id){
                console.log("Details of Array " + details[key].courses.split(','));
                courseArray = details[key].courses.split(',');
                return courseArray
              }
            }
          }
        })
      ).then(function(value){
        return value;
      })
    }

ma​​in_page.js:导出UniqueCourse函数供外部使用

    module.exports.UniqueCourse = (t_id) => {
        return UniqueCourse(t_id)
    }

index.js:获取从 main_page.js 中 UniqueCourse 函数传递的列表

    Promise.resolve(main_page.UniqueCourse(req.body.username)).then(function(value){
      console.log(value);
     })

index.js 中的 console.log(value) 应该包含 UniqueCourse(t_id) 中的课程列表。但是,我得到的是console.log(value) 上显示的promise 对象。我很难从 promise 对象访问列表。

控制台输出

    Details of Array CZ4047,CZ3003

    DataSnapshot {
      node_:
       ChildrenNode {
         children_:
          SortedMap { comparator_: [Function: NAME_COMPARATOR], root_: [LLRBNode] },
         priorityNode_:
          ChildrenNode {
            children_: [SortedMap],
            priorityNode_: null,
            indexMap_: [IndexMap],
            lazyHash_: '' },
         indexMap_: IndexMap { indexes_: [Object], indexSet_: [Object] },
         lazyHash_: null },
      ref_:
       Reference {
         repo:
          Repo {
            repoInfo_: [RepoInfo],
            app: [FirebaseAppImpl],
            dataUpdateCount: 2,
            statsListener_: null,
            eventQueue_: [EventQueue],
            nextWriteId_: 1,
            interceptServerDataCallback_: null,
            onDisconnect_: [SparseSnapshotTree],
            persistentConnection_: [PersistentConnection],
            stats_: [StatsCollection],
            server_: [PersistentConnection],
            statsReporter_: [StatsReporter],
            transactionQueueTree_: [Tree],
            infoData_: [SnapshotHolder],
            infoSyncTree_: [SyncTree],
            serverSyncTree_: [SyncTree],
            __database: [Database] },
         path: Path { pieces_: [Array], pieceNum_: 0 },
         queryParams_:
          QueryParams {
            limitSet_: false,
            startSet_: false,
            startNameSet_: false,
            endSet_: false,
            endNameSet_: false,
            limit_: 0,
            viewFrom_: '',
            indexStartValue_: null,
            indexStartName_: '',
            indexEndValue_: null,
            indexEndName_: '',
            index_: PriorityIndex {} },
         orderByCalled_: false },
      index_: PriorityIndex {} }

预期的控制台输出

    Details of Array CZ4047,CZ3003

    [CZ4047,CZ3003]

【问题讨论】:

  • 不要在答案中加入“已解决”部分。这不是 Stack Overflow 的工作方式。问题的答案应该在答案部分。如果您自己有一个尚未发布的答案,请自己发布一个。这在 Stack Overflow 上是可以接受的。
  • Promise.resolve(anotherPromise)的原因是什么?

标签: javascript node.js function express promise


【解决方案1】:

我对 firebase 几乎没有经验,但我认为您可以将查询重写为

function UniqueCourse(t_id) {
    return firebase.database()
        .ref('/users')
        .orderByChild('username').equalTo(t_id)
        .child('courses')
        .once('value')
        .then(snapshot => snapshot.exists() ? 
            snapshot.val()[0].split(",") : 
            []
         );
}

因此,您不会下载所有用户,只是为了获取其中一个用户的字符串。相反,您只下载您想要的实际数据;与过滤器匹配的用户的课程。

【讨论】:

    【解决方案2】:

    如果您正在处理 Promise,您可以使用 async/await 避免 .then 循环。要使用 async/await,请使用 babel 将代码转换为您的 Node 版本支持的版本。

    // Get Unique Course ID
        function sync UniqueCourse(t_id){
          var courseArray = []
          const snapshot = await firebase.database().ref('/users').once('value')
          const details = snapshot.val();
          for (var key in details) {
              if (details.hasOwnProperty(key)) {
                //console.log(key + " , " + details[key].username + "\n");
                if (details[key].username == t_id){
                  console.log("Details of Array " + details[key].courses.split(','));
                  courseArray = details[key].courses.split(',');
                }
              }
            }
          return courseArray
        }
    

    【讨论】:

      【解决方案3】:

      解决方案

      通过将逻辑移到 firebase 数据快照上的 Promise 后面来解决问题。

          // Get Unique Course ID
          function UniqueCourse(t_id){
            var courseArray = []
            return Promise.resolve(
              firebase.database().ref('/users').once('value',function(snapshot) {})
              ).then(function(snapshot){
      
              details = snapshot.val();
              //console.log(snapshot.val());
      
              for (var key in details) {
                if (details.hasOwnProperty(key)) {
                  //console.log(key + " , " + details[key].username + "\n");
                  if (details[key].username == t_id){
                    console.log("Details of Array " + details[key].courses.split(','));
                    courseArray = details[key].courses.split(',');
                  }
                }
              }
              return courseArray;
              })
          }
      

      【讨论】:

        【解决方案4】:

        根据firebase doconce 方法返回一个Promise<DataSnapshot>

        return Promise.resolve(
            firebase.database().ref("xxx").once(function () { /* ..logic.. */ })
        ).then(function (value) { // this is 'DataSnapshot'
            return value;
        })
        

        您从 DataSnapshot 中获取值并返回如下

        return Promise.resolve(
            firebase.database().ref("xxx").once(function () { /* ..logic.. */ })
        ).then(function (snapshot) {
            return snapshot.val(); // I believe this is syntax. please check the docs
        })
        

        【讨论】:

        • @ChristopherTan 如果您觉得这有帮助,请点赞
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-12-18
        • 1970-01-01
        • 2018-07-27
        • 1970-01-01
        • 2021-07-11
        相关资源
        最近更新 更多