forked from sam/fedifeed
make promise chaining more sustainable
This commit is contained in:
parent
49f6a0b8e2
commit
9d85c029f4
1 changed files with 37 additions and 20 deletions
|
@ -3,16 +3,25 @@ var fs = require('fs');
|
|||
var template = ejs.compile(fs.readFileSync('./lib/template.ejs', 'utf8'));
|
||||
var timeAgo = require('timeago.js');
|
||||
|
||||
// TODO try https://www.npmjs.com/package/request-promise-cache for the requests
|
||||
var request = require('request-promise-cache')
|
||||
|
||||
const hour = 3600000;
|
||||
|
||||
// get JSON for an AP URL
|
||||
// TODO make it reject on HTTP 4xx or 5xx
|
||||
// get JSON for an AP URL, by either fetching it or grabbing it from a cache.
|
||||
|
||||
// Honestly request-promise-cache should be good enough. Redis would be a nice upgrade but for
|
||||
// a single process install it will be fine.
|
||||
|
||||
// note: rejects on HTTP 4xx or 5xx
|
||||
async function apGet(url,ttl) {
|
||||
|
||||
return new Promise(function(resolve,reject){
|
||||
|
||||
// fail early
|
||||
if (!url){
|
||||
reject(new Error('URL is invalid'));
|
||||
}
|
||||
|
||||
request( {
|
||||
uri:url,
|
||||
cacheKey:url,
|
||||
|
@ -29,13 +38,24 @@ async function apGet(url,ttl) {
|
|||
|
||||
}
|
||||
|
||||
// never rejects, instead it returns an object with a status, error and/or result.
|
||||
async function apGetNoReject(...args){
|
||||
return new Promise(function(resolve,reject){
|
||||
apGet(...args)
|
||||
.then(res=>resolve({status:true,result:res}))
|
||||
.catch(e=>resolve({status:false,error:e}))
|
||||
});
|
||||
// like Promise.all except returns null on error instead of failing all the promises
|
||||
async function promiseSome(proms){
|
||||
|
||||
function noRejectWrap(prom){
|
||||
return new Promise(function(resolve,reject){
|
||||
|
||||
prom // it's already been called
|
||||
.then(resolve)
|
||||
.catch(e=>{
|
||||
// console.warn(e);// for debugging
|
||||
resolve(null)
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
return await Promise.all(proms.map(noRejectWrap))
|
||||
|
||||
}
|
||||
|
||||
module.exports = async function (opts) {
|
||||
|
@ -97,16 +117,15 @@ async function itemsForFeed(opts,user,feed) {
|
|||
var boostData = [];
|
||||
var boostUrls = feed.orderedItems.filter(i=>i.type=="Announce").map(i=>i.object);
|
||||
// console.log(boostUrls);
|
||||
boostData = await Promise.all(boostUrls.map(apGetNoReject));
|
||||
boostData = boostData.map(d=>d.result||{});
|
||||
boostData = await promiseSome(boostUrls.map(apGet));
|
||||
|
||||
// now get user data for each of those
|
||||
let userData = await Promise.all(boostData.map(d=>d.attributedTo||'').map(apGetNoReject));
|
||||
let userData = await promiseSome(boostData.map(d=>d?d.attributedTo||'':null).map(apGet));
|
||||
|
||||
// put a ._userdata key on the item object if this is a boost etc
|
||||
// put a ._userdata key on the item object if this is a boost
|
||||
for (var i = 0; i < boostData.length; i ++){
|
||||
if (userData[i].status){
|
||||
boostData[i]._userdata = userData[i].result;
|
||||
if (userData[i] && boostData[i]){
|
||||
boostData[i]._userdata = userData[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,8 +135,8 @@ async function itemsForFeed(opts,user,feed) {
|
|||
|
||||
boostData.forEach((boostToot)=>{
|
||||
|
||||
if (!boostToot.id){
|
||||
return;// case where it's a {} b/c the request failed or w/e
|
||||
if (!boostToot){// failed request
|
||||
return;
|
||||
}
|
||||
|
||||
// inject in-place into items
|
||||
|
@ -142,8 +161,6 @@ async function itemsForFeed(opts,user,feed) {
|
|||
|
||||
|
||||
return items.filter((item)=>{
|
||||
// this is temporary, don't handle boosts (TODO)
|
||||
// return item.type == "Create" && item.object && item.object.type=="Note";
|
||||
return typeof item.object == 'object';// handle weird cases
|
||||
}).map((item)=>{
|
||||
|
||||
|
|
Loading…
Reference in a new issue