Вы должны использовать try catch в этом коде
getFriendsPosts = async (user,callback) => {
const arr = [];
const array = [];
const db = await MongoClient.connect(url);
const dbo = db.db("drone-x");
const results = await dbo.collection("users").find({_id: ObjectId(user.id)})
const resultPromise = _.map(results, async element => {
const friends = _.get(element, 'friends', [])
if(friends.length != 0) {
const friendPromise = _.map(friends, async friend => {
const ress = await dbo.collection("users").find({_id: ObjectId(friend.id)})
arr.push(ress);
const resPromise = _.map(ress, async res => {
const posts = await dbo.collection("posts").find({userId: res._id.toString()})
const postPromise = _.map(posts, post => {
array.push(post);
})
await Promise.all(postPromise)
})
await Promise.all(resPromise)
})
await Promise.all(friendPromise)
}
})
await Promise.all(resultPromise)
return { arr , array }
}
Я не рекомендую, чтобы это занимало слишком много времени. Вы должны использовать мангуста и использовать агрегацию для длинных запросов.
Да, вам нужно использовать Decimal.GetBits
. К сожалению, вам придется работать с 96-разрядным целым числом, и в .NET нет простого целочисленного типа, который бы справлялся с 96-разрядным. С другой стороны, возможно, что вы могли бы использовать Decimal
сам ...
Вот некоторый код, который выдает те же числа, что и ваши примеры. Надеюсь, вы найдете это полезным:)
using System;
public class Test
{
static public void Main(string[] x)
{
ShowInfo(123.4500m);
ShowInfo(0m);
ShowInfo(0.0m);
ShowInfo(12.45m);
ShowInfo(12.4500m);
ShowInfo(770m);
}
static void ShowInfo(decimal dec)
{
// We want the integer parts as uint
// C# doesn't permit int[] to uint[] conversion,
// but .NET does. This is somewhat evil...
uint[] bits = (uint[])(object)decimal.GetBits(dec);
decimal mantissa =
(bits[2] * 4294967296m * 4294967296m) +
(bits[1] * 4294967296m) +
bits[0];
uint scale = (bits[3] >> 16) & 31;
// Precision: number of times we can divide
// by 10 before we get to 0
uint precision = 0;
if (dec != 0m)
{
for (decimal tmp = mantissa; tmp >= 1; tmp /= 10)
{
precision++;
}
}
else
{
// Handle zero differently. It's odd.
precision = scale + 1;
}
uint trailingZeros = 0;
for (decimal tmp = mantissa;
tmp % 10m == 0 && trailingZeros < scale;
tmp /= 10)
{
trailingZeros++;
}
Console.WriteLine("Example: {0}", dec);
Console.WriteLine("Precision: {0}", precision);
Console.WriteLine("Scale: {0}", scale);
Console.WriteLine("EffectivePrecision: {0}",
precision - trailingZeros);
Console.WriteLine("EffectiveScale: {0}", scale - trailingZeros);
Console.WriteLine();
}
}
Использование ToString примерно в 10 раз быстрее, чем решение Джона Скита. Несмотря на то, что это достаточно быстро, задача здесь (если есть кто-нибудь!) Состоит в том, чтобы побить производительность ToString.
Результаты производительности, которые я получаю от следующей тестовой программы: ShowInfo 239 мс FastInfo 25 мс
using System;
using System.Diagnostics;
using System.Globalization;
public class Test
{
static public void Main(string[] x)
{
Stopwatch sw1 = new Stopwatch();
Stopwatch sw2 = new Stopwatch();
sw1.Start();
for (int i = 0; i < 10000; i++)
{
ShowInfo(123.4500m);
ShowInfo(0m);
ShowInfo(0.0m);
ShowInfo(12.45m);
ShowInfo(12.4500m);
ShowInfo(770m);
}
sw1.Stop();
sw2.Start();
for (int i = 0; i < 10000; i++)
{
FastInfo(123.4500m);
FastInfo(0m);
FastInfo(0.0m);
FastInfo(12.45m);
FastInfo(12.4500m);
FastInfo(770m);
}
sw2.Stop();
Console.WriteLine(sw1.ElapsedMilliseconds);
Console.WriteLine(sw2.ElapsedMilliseconds);
Console.ReadLine();
}
// Be aware of how this method handles edge cases.
// A few are counterintuitive, like the 0.0 case.
// Also note that the goal is to report a precision
// and scale that can be used to store the number in
// an SQL DECIMAL type, so this does not correspond to
// how precision and scale are defined for scientific
// notation. The minimal precision SQL decimal can
// be calculated by subtracting TrailingZeros as follows:
// DECIMAL(Precision - TrailingZeros, Scale - TrailingZeros).
//
// dec Precision Scale TrailingZeros
// ------- --------- ----- -------------
// 0 1 0 0
// 0.0 2 1 1
// 0.1 1 1 0
// 0.01 2 2 0 [Diff result than ShowInfo]
// 0.010 3 3 1 [Diff result than ShowInfo]
// 12.45 4 2 0
// 12.4500 6 4 2
// 770 3 0 0
static DecimalInfo FastInfo(decimal dec)
{
string s = dec.ToString(CultureInfo.InvariantCulture);
int precision = 0;
int scale = 0;
int trailingZeros = 0;
bool inFraction = false;
bool nonZeroSeen = false;
foreach (char c in s)
{
if (inFraction)
{
if (c == '0')
trailingZeros++;
else
{
nonZeroSeen = true;
trailingZeros = 0;
}
precision++;
scale++;
}
else
{
if (c == '.')
{
inFraction = true;
}
else if (c != '-')
{
if (c != '0' || nonZeroSeen)
{
nonZeroSeen = true;
precision++;
}
}
}
}
// Handles cases where all digits are zeros.
if (!nonZeroSeen)
precision += 1;
return new DecimalInfo(precision, scale, trailingZeros);
}
struct DecimalInfo
{
public int Precision { get; private set; }
public int Scale { get; private set; }
public int TrailingZeros { get; private set; }
public DecimalInfo(int precision, int scale, int trailingZeros)
: this()
{
Precision = precision;
Scale = scale;
TrailingZeros = trailingZeros;
}
}
static DecimalInfo ShowInfo(decimal dec)
{
// We want the integer parts as uint
// C# doesn't permit int[] to uint[] conversion,
// but .NET does. This is somewhat evil...
uint[] bits = (uint[])(object)decimal.GetBits(dec);
decimal mantissa =
(bits[2] * 4294967296m * 4294967296m) +
(bits[1] * 4294967296m) +
bits[0];
uint scale = (bits[3] >> 16) & 31;
// Precision: number of times we can divide
// by 10 before we get to 0
uint precision = 0;
if (dec != 0m)
{
for (decimal tmp = mantissa; tmp >= 1; tmp /= 10)
{
precision++;
}
}
else
{
// Handle zero differently. It's odd.
precision = scale + 1;
}
uint trailingZeros = 0;
for (decimal tmp = mantissa;
tmp % 10m == 0 && trailingZeros < scale;
tmp /= 10)
{
trailingZeros++;
}
return new DecimalInfo((int)precision, (int)scale, (int)trailingZeros);
}
}