javascript - promise 不会解决

标签 javascript node.js promise

下面 Promise 的第二部分(在 then 内)永远不会运行。当我在不使用 Promise 的情况下运行数据库查询时(在我运行 node myscript.js 的 Node 脚本中,它返回数据,但控制台永远不会返回提示 - 控制台只是挂起,我必须手动发送中断。因此,当我将其放入 Promise 中时,我认为 Promise 不知道数据库查询已完成,即使它似乎已返回所有数据,因此 Promise 的第二部分未运行(我认为)。如果这是问题所在,如何编写数据库查询,使其不会挂起并且 Promise 可以运行完成?

const sqlite = require('/usr/local/lib/node_modules/sqlite3');
const express = require('/usr/local/lib/node_modules/express')
const promise = require('/usr/local/lib/node_modules/promise')

app.get('/', (request, res) => {

  var res = [];

  function getData() {
    return new Promise(function(resolve, reject) {
      db.each('SELECT column_a, column_b FROM trips group by column_a', (e, rows) => {

        var d = {
          a: rows['column_a'],
          b: rows['column_b']
        }


        res.push(d)
      });
    });

  }
  getData().then(function(data) {
    console.log("never run....", res, data) //never run
  });

})

最佳答案

您需要通过其构造函数调用回调中提供的函数之一来解决 promise 。

const promise = new Promise((resolve, reject) => {
  // you must call resolve() or reject() here
  // otherwise the promise never resolves
});

否则它将始终处于Pending状态,并且永远不会调用您传递给then的回调。

promise.then(() => {
  // this never gets called if we don't resolve() or reject()
});

此外,Promise 允许您使用值进行解析,因此通常不需要维护全局变量,您只需传递结果即可。

最后,db.each 中的回调将每行调用一次,因此您需要在获取所有行后通过解析 promise 来处理该问题

以下是编写代码的方法:

function getData() {
  const data = [];
  return new Promise((resolve, reject) => {
    db.each('SELECT column_a, column_b FROM trips group by column_a', (e, row) => {
      if (e) {
        // error reading a row, reject the Promise immediately
        // optionally you could accumulate errors here in a similar manner to rows
        reject(e); 
        return;
      } 

      // success reading a row, store the row result
      data.push({
        a: row['column_a'],
        b: row['column_b']
      });

    }, (e, rowCount) => { // the complete handler called when the operation is done, see docs: https://github.com/mapbox/node-sqlite3/wiki/API#databaseeachsql-param--callback-complete

      if (e) { 
        // operation finished, there was an error
        reject(e);
        return;
      }

      // operation succeeded, resolve with rows
      resolve(data);
    });
  });
}

app.get('/', (request, res) => {  

  getData().then((data) => {
    // here `data` is an array of row objects
  }, (e) => {
    console.error(`Database error: ${e}`);
  });
});

旁注

不确定为什么要将参数 res 重新声明为 [],但不需要执行 var res = []。由于您已经有了 res,您只需说 res = []res 指向一个新数组。当然,这将覆盖响应对象,因此我假设您这样做只是为了本示例的目的。如果没有,您可能应该创建一个新变量。

关于javascript - promise 不会解决,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39580345/

相关文章:

javascript - 如何使用 Javascript Promise 在循环中按顺序执行 AJAX 调用

javascript - 检查另一个对象中是否存在键/值对

javascript - 在 Angular2 中使用 Parse 作为模块

node.js - NodeJS ip 分片

javascript - 在 Node.js 中编写非阻塞函数的正确方法

javascript - 链接两个异步 jQuery 函数时如何完全避开 jQuery promise ?

javascript - 如何为包含 HTML 和 JavaScript 或 jQuery 的网页编写 Jasmine 测试?

node.js - Heroku 上的 Clojurescript

javascript - new Date() 会导致 Node.js 中的内存泄漏吗?

javascript - Promise 回调中的异步函数