用承诺解决游标

时间:2018-10-25 21:37:30

标签: javascript node.js

我正在尝试向Twitter API查询用户的关注者,以比较两者。我正在使用游标检索用户列表。我使用promise进行设置,第一个get请求将用户的关注者限制到一个极限,然后查找游标,将数据传递到数组中,然后将游标的值解析为相同的重复函数,直到游标返回0,发生这种情况时,我想全部以分辨率发送。当我设置最初的承诺并使用promise.all来解决它们并附加.then时,即为承诺。一切先解决。我已经尝试从循环函数中解析promise,然后将另一个promise返回到第一个函数,但是我似乎无法使它起作用。有什么想法吗?

const express = require("express");
const router = express.Router();
const twitter = require("../controllers/twitter");

let object1 = {
  params: {
    screen_name: "xxxx",
    count: "40"
  }
};
let object = {
  params: {
    screen_name: "xxxxx",
    count: "40"
  }
};
let data = [];
router.get("", (req, res, next) => {
  let one = getUserFollowers("/1.1/followers/ids.json", object);
  let two = getUserFollowers("/1.1/followers/ids.json", object1);
  Promise.all([one, two]).then(console.log);
});

function getUserFollowers(uri, parameters) {
  twitter
    .get(uri, parameters)
    .then(resp => {
      let ids = resp.data.ids;
      data.push(...ids);

      return recurr(resp, uri, parameters);
    })
    .then(data => {
    //if instead I re console.log the data I can get it, but I need to resolve it back in the router so I can send it as a res. 
      return new Promise((resolve, reject) => {
        resolve(data);
        reject(error);
      });
    });
}

let recurr = (response, uri, params) => {
  if (response.data.next_cursor > 0) {
    params.params.cursor = response.data.next_cursor;
    return getUserFollowers(uri, params);
  } else {
    return Promise.resolve(data);
  }
};

module.exports = router;

1 个答案:

答案 0 :(得分:1)

您的代码中的错误:

getUserFollowers不返回任何内容-因此,让我们在twitter.get

之前添加一个返回值
.then(data => {
//if instead I re console.log the data I can get it, but I need to resolve it back in the router so I can send it as a res. 
  return new Promise((resolve, reject) => {
    resolve(data);
    reject(error);
  });
});

出于多种原因,这没有任何意义。

  1. 您只能一次“完成”一个Promise,因此在解决问题后加上拒绝意味着仅解决问题得以执行...
  2. .then总是返回一个promise,因此当.then仅包含同步代码时,通常不需要Promise构造函数;和
  3. 您实际上正在做的是无操作...您已经在{.1}中收到data,对此一无所获,并且以一种复杂的方式,将数据返回了另一端。

由于recurr仅在.then内部被调用,因此您不必保证使用Promise.resolve返回Promise-但是,我将完全失去递归函数,它只是用简单的代码使事情复杂化

您有一个全局data变量同时由两个getUserFollowers推送数据的事实也可能会给您带来麻烦

重写以解决上述所有问题,您将获得:

const express = require("express");
const router = express.Router();
const twitter = require("../controllers/twitter");

let object1 = {
  params: {
    screen_name: "xxxx",
    count: "40"
  }
};
let object = {
  params: {
    screen_name: "xxxxx",
    count: "40"
  }
};

router.get("", (req, res, next) => {
    let one = getUserFollowers("/1.1/followers/ids.json", object, []);
    let two = getUserFollowers("/1.1/followers/ids.json", object1, []);
    Promise.all([one, two]).then(console.log);
});

function getUserFollowers(uri, parameters, data) {
    return twitter
    .get(uri, parameters)
    .then(resp => {
        let ids = resp.data.ids;
        data.push(...ids);
        if (resp.data.next_cursor > 0) {
            params.params.cursor = response.data.next_cursor;
            return getUserFollowers(uri, params, data);
        }
        return data;
    });
}

module.exports = router;