Repository: dask/dask

Issue:
Different output for to_json(compute=False) and  to_json(compute=True) 
<!-- Please include a self-contained copy-pastable example that generates the issue if possible.

Please be concise with code posted. See guidelines below on how to provide a good bug report:

- Craft Minimal Bug Reports http://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports
- Minimal Complete Verifiable Examples https://stackoverflow.com/help/mcve

Bug reports that follow these guidelines are easier to diagnose, and so are often handled much more quickly.
-->

**What happened**:

I'm trying to save a dataframe with more than 1 partition to a json file. For this, I'm using an asynchronous client to compute the save later. The issue is that after waiting  the return is a list full of None objects.

**What you expected to happen**:

I expected to return the same as when using `to_json(df, path, compute=True)`

**Minimal Complete Verifiable Example**:

```python
async def save_to_json(data, path):
    client = Client.current(allow_global=False)
    files = to_json(data, path, compute=False)
    files = client.compute(files)
    return await asyncio.gather(*files)
```

**Anything else we need to know?**:

I think the issue comes from what's been returned in to_json() and that write_json_partition() doesn't return anything.

```python
parts = [
    delayed(write_json_partition)(d, outfile, kwargs)
    for outfile, d in zip(outfiles, df.to_delayed())
]
if compute:
    if compute_kwargs is None:
        compute_kwargs = dict()
    dask_compute(parts, **compute_kwargs)
    return [f.path for f in outfiles]
else:
    return parts #, [f.path for f in outfiles] This does the trick for now for me
```

I think this issue is also present in DataFrame.to_csv()

**Environment**:

- Dask version: 2021.11.2
- Python version: 3.8
- Operating System: macOS Monterey 12.1
- Install method (conda, pip, source): pip

<!-- If you are reporting an issue such as scale stability, cluster deadlock.
Please provide a cluster dump state with this issue, by running client.dump_cluster_state()

https://distributed.dask.org/en/stable/api.html?highlight=dump_cluster_state#distributed.Client.dump_cluster_state

-->

<details>
<summary>Cluster Dump State:</summary>

</details>


Discussion:
Ah that's a good point. In case it's not clear, the operation is working (the data is being written to the file), it's just that the return isn't very informative. 

I have a super-minimal example that I was messing around with:

```python
import dask

ddf = dask.datasets.timeseries(freq="1H")
dask.compute(ddf.to_json("data.json", compute=False))
```

I think the solution is exactly what you are pointing to, but I think it's the return on `write_json_partition` that should be changed. I'll open a PR in a few minutes.

Resolving patch:
diff --git a/dask/dataframe/io/csv.py b/dask/dataframe/io/csv.py
--- a/dask/dataframe/io/csv.py
+++ b/dask/dataframe/io/csv.py
@@ -1,3 +1,4 @@
+import os
 from collections.abc import Mapping
 from io import BytesIO
 from warnings import catch_warnings, simplefilter, warn
@@ -766,7 +767,7 @@ def read(
 def _write_csv(df, fil, *, depend_on=None, **kwargs):
     with fil as f:
         df.to_csv(f, **kwargs)
-    return None
+    return os.path.normpath(fil.path)
 
 
 def to_csv(
@@ -953,8 +954,7 @@ def to_csv(
 
         import dask
 
-        dask.compute(*values, **compute_kwargs)
-        return [f.path for f in files]
+        return list(dask.compute(*values, **compute_kwargs))
     else:
         return values
 
diff --git a/dask/dataframe/io/json.py b/dask/dataframe/io/json.py
--- a/dask/dataframe/io/json.py
+++ b/dask/dataframe/io/json.py
@@ -1,4 +1,5 @@
 import io
+import os
 
 import pandas as pd
 from fsspec.core import open_files
@@ -90,8 +91,7 @@ def to_json(
     if compute:
         if compute_kwargs is None:
             compute_kwargs = dict()
-        dask_compute(parts, **compute_kwargs)
-        return [f.path for f in outfiles]
+        return list(dask_compute(*parts, **compute_kwargs))
     else:
         return parts
 
@@ -99,6 +99,7 @@ def to_json(
 def write_json_partition(df, openfile, kwargs):
     with openfile as f:
         df.to_json(f, **kwargs)
+    return os.path.normpath(openfile.path)
 
 
 @insert_meta_param_description


Test patch:
diff --git a/dask/dataframe/io/tests/test_csv.py b/dask/dataframe/io/tests/test_csv.py
--- a/dask/dataframe/io/tests/test_csv.py
+++ b/dask/dataframe/io/tests/test_csv.py
@@ -1305,13 +1305,20 @@ def test_to_csv():
 
         with tmpdir() as dn:
             r = a.to_csv(dn, index=False, compute=False)
-            dask.compute(*r, scheduler="sync")
+            paths = dask.compute(*r, scheduler="sync")
+            # this is a tuple rather than a list since it's the output of dask.compute
+            assert paths == tuple(
+                os.path.join(dn, f"{n}.part") for n in range(npartitions)
+            )
             result = dd.read_csv(os.path.join(dn, "*")).compute().reset_index(drop=True)
             assert_eq(result, df)
 
         with tmpdir() as dn:
             fn = os.path.join(dn, "data_*.csv")
-            a.to_csv(fn, index=False)
+            paths = a.to_csv(fn, index=False)
+            assert paths == [
+                os.path.join(dn, f"data_{n}.csv") for n in range(npartitions)
+            ]
             result = dd.read_csv(fn).compute().reset_index(drop=True)
             assert_eq(result, df)
 
diff --git a/dask/dataframe/io/tests/test_json.py b/dask/dataframe/io/tests/test_json.py
--- a/dask/dataframe/io/tests/test_json.py
+++ b/dask/dataframe/io/tests/test_json.py
@@ -4,6 +4,7 @@
 import pandas as pd
 import pytest
 
+import dask
 import dask.dataframe as dd
 from dask.dataframe.utils import assert_eq
 from dask.utils import tmpdir, tmpfile
@@ -135,3 +136,17 @@ def test_read_json_inferred_compression():
         dd.to_json(ddf, fn, compression="gzip")
         actual = dd.read_json(fn)
         assert_eq(df, actual.compute(), check_index=False)
+
+
+def test_to_json_results():
+    with tmpfile("json") as f:
+        paths = ddf.to_json(f)
+        assert paths == [os.path.join(f, f"{n}.part") for n in range(ddf.npartitions)]
+
+    with tmpfile("json") as f:
+        list_of_delayed = ddf.to_json(f, compute=False)
+        paths = dask.compute(*list_of_delayed)
+        # this is a tuple rather than a list since it's the output of dask.compute
+        assert paths == tuple(
+            os.path.join(f, f"{n}.part") for n in range(ddf.npartitions)
+        )