简化交错的flatMap Observable链

时间:2016-02-11 15:31:09

标签: java rx-java

我想从我的存储库中检索一个对象列表,然后在实际有机会使用检索到的列表之前清除我的存储库的内容。目前,我有几个交错的flatMaps,但我想这是一个更好的方法。这就是我的Observables链的样子:

using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace MultilineTextFieldDemo
{
    public class PdfCreator
    {
        public static void Main(string[] args)
        {
            string outputDirName = "PdfOutput",
                   outputFilePath = "";
            byte[] buf = null;

            if (!Directory.Exists(outputDirName))
            {
                Directory.CreateDirectory(outputDirName);
            }

            // Create a PDF form with NeedAppearances = true.
            //
            // PRO: The text field will have a consistent appearance, whether it's focused or not.
            // CON: Adobe Reader will prompt you to save changes when you try to close the file,
            //      even if you haven't changed anything.

            buf = CreatePdf(true);
            if (buf != null && buf.Length > 0)
            {
                outputFilePath = Path.Combine(outputDirName, "PdfTest_NeedAppsTrue.pdf");
                File.WriteAllBytes(outputFilePath, buf);
            }

            // Create a PDF form with NeedAppearances = false.
            //
            // PRO: Adobe Reader won't prompt you to save changes when you close the file, unless
            //      you actually changed something.
            // CON: The text field's appearance will change when it gains or loses focus; the characters
            //      will be slightly closer together when focused, and some lines will change their
            //      wrapping positions.

            buf = CreatePdf(false);
            if (buf != null && buf.Length > 0)
            {
                outputFilePath = Path.Combine(outputDirName, "PdfTest_NeedAppsFalse.pdf");
                File.WriteAllBytes(outputFilePath, buf);
            }
        }

        public static byte[] CreatePdf(bool needAppearances)
        {
            byte[] buf = null;
            float marginsH = Utilities.InchesToPoints(0.65f),
                  marginsV = Utilities.InchesToPoints(0.5f);

            using (MemoryStream ms = new MemoryStream())
            {
                using (Document doc = new Document(PageSize.LETTER, marginsH, marginsH, marginsV, marginsV))
                {
                    using (PdfWriter writer = PdfWriter.GetInstance(doc, ms))
                    {
                        if (needAppearances)
                        {
                            writer.AcroForm.NeedAppearances = true;
                        }

                        doc.Open();

                        // Create and add a label for the text field.

                        Phrase label = new Phrase(
                            String.Format("Text Field (NeedAppearances = {0})", needAppearances),
                            FontFactory.GetFont(BaseFont.HELVETICA, 10, Font.BOLD));
                        doc.Add(label);

                        // Calculate the text field's rectangle. It will be the full width of the document, minus a 2-point
                        // margin on the left and right. Its top edge will be directly under the label, and it will be
                        // 4 inches tall.

                        float llx = doc.GetLeft(2),
                              urx = doc.GetRight(2),
                              ury = doc.GetTop(0) - label.Font.CalculatedSize,
                              lly = ury - Utilities.InchesToPoints(4);

                        // Create the text field.

                        TextField textField = new TextField(writer, new Rectangle(llx, lly, urx, ury), "textField");
                        textField.FontSize = 8;
                        textField.Options = BaseField.MULTILINE;
                        textField.Text =
                            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ac convallis libero, quis bibendum " +
                            "risus. Vestibulum gravida aliquam tellus, pharetra semper nulla vulputate nec. Nunc eu ornare " +
                            "ligula. Proin pulvinar erat elit, ac elementum ex placerat in. Sed ligula nisl, viverra hendrerit " +
                            "elit ut, lacinia semper diam. Nam in felis fringilla, dignissim metus et, tristique diam. Proin " +
                            "sodales eros non tellus aliquet bibendum. Fusce volutpat, massa at tincidunt porta, dolor justo " +
                            "tincidunt mi, non iaculis justo sem ac erat. Sed dapibus urna vel hendrerit fermentum. Sed rutrum " +
                            "augue sapien, id suscipit nisi porta eu. Morbi vel leo ut tortor faucibus sagittis. Etiam in maximus " +
                            "dui. Quisque et mattis ligula. Integer cursus suscipit semper. Fusce commodo tellus in mattis " +
                            "lobortis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.";

                        // If NeedAppearances is false, add a vertical margin to compensate for the text shifting downward
                        // when the field gains focus (this still doesn't fix the character spacing issue).

                        if (!needAppearances)
                        {
                            textField.SetExtraMargin(0, 2.8f);
                        }

                        // Get the text field's annotation and add it to the document.

                        PdfFormField annot = textField.GetTextField();
                        writer.AddAnnotation(annot);

                        doc.Close();
                    }
                }

                buf = ms.ToArray();
            }

            return buf;
        }
    }
}

任何想法如何简化它?

2 个答案:

答案 0 :(得分:1)

你的代码很好。唯一的优化是内部flatMap,它只能是map

mQueuedCallsRepository.getAll()
    .subscribeOn(Schedulers.io())
    .flatMap(queuedCallModels -> {
            return mQueuedCallsRepository.clear()
                    .doOnNext(aVoid -> disableReceiver(context))
                    .map( aVoid -> queuedCallModels);
    });

这是逻辑:

  • 获取所有数据并在IO线程中运行操作
  • 当您清楚地了解数据时(
  • 当清除操作成功时,禁用接收器
  • 然后返回您之前获得的所有数据

答案 1 :(得分:0)

不确定为什么你需要flatMap什么都不做:

new Func1<QueuedCallModel[], Observable<QueuedCallModel[]>>

您可以在根doOnNext上使用Observable运算符,清除存储库,然后返回您的数据:

Observable
        .just(new Object())
        .doOnNext(result -> System.out.println("clear"))//clearing
        .subscribe(result -> {
            //delivers result which already deleted from repository
            System.out.println("use:" + result);
        });