web-dev-qa-db-ja.com

promiseのfs.writeFile、非同期同期のもの

私は自分のコードに関して助けが必要です。私はNode.jsの初心者であり、多くの問題を抱えています。

私がやろうとしていること:

1).txtをAmazon製品(ASIN)で取得します。

2) Amazon-product-api パッケージを使用してすべての製品を取得します。

3)各製品を.jsonファイルに保存します。

コードが機能しません。私はこの非同期同期のもので台無しになったと思う-助けて!

var Amazon = require('Amazon-product-api');
var fs = require('fs');

var client = Amazon.createClient({
    awsId: "XXX",
    awsSecret: "XXX",
    awsTag: "888"
});

var array = fs.readFileSync('./test.txt').toString().split('\n');
for (var i = 1; i < array.length; i++) {
     var ASIN = array[i];

    return client.itemLookup({
            domain: 'webservices.Amazon.de',
            responseGroup: 'Large',
            idType: 'ASIN',
            itemId: ASIN
        })
        .then(function(results) {
            fs.writeFile(ASIN + '.json', JSON.stringify(results), function(err) {
                if (err) {
                    console.log(err);
                } else {
                    console.log("JSON saved");
                }
            })

            return results;

        }).catch(function(err) {
            console.log(err);
        });
};
40

2019年現在...

...正しい答えは、ネイティブfs promisesモジュール ノードに含まれるasync/awaitを使用することです 。 Node.js 10または11(主要なクラウドプロバイダーで既にサポートされています)にアップグレードして、これを実行します。

const fs = require('fs').promises;

// This must run inside a function marked `async`:
const file = await fs.readFile('filename.txt', 'utf8');
await fs.writeFile('filename.txt', 'test');

サードパーティのパッケージを使用せず、独自のラッパーを作成しないでください。これはもう必要ありません。

もはや実験的ではない

Node 11.14.0の前に、この機能は実験的であるという警告が表示されますが、正常に機能し、今後の方法です。 11.14.0以降、この機能は実験段階ではなく、本番環境で使用できます。

importではなくrequireを好む場合はどうなりますか?

それも機能します-ただし、この機能が実験的としてマークされていないNode.jsバージョンでのみです。

import { promises as fs } from 'fs';

(async () => {
    await fs.writeFile('./test.txt', 'test', 'utf8');
})();
63
K48

fs.writefileは従来の非同期コールバックであるため、promiseの仕様に従って、次のような解決および拒否ハンドラーでラップする新しいpromiseを返す必要があります。

return new Promise(function(resolve, reject) {
    fs.writeFile("<filename.type>", data, '<file-encoding>', function(err) {
        if (err) reject(err);
        else resolve(data);
    });
});

したがって、コードでは、.then()を呼び出した直後にそのように使用します。

 .then(function(results) {
    return new Promise(function(resolve, reject) {
            fs.writeFile(ASIN + '.json', JSON.stringify(results), function(err) {
               if (err) reject(err);
               else resolve(data);
            });
    });
  }).then(function(results) {
       console.log("results here: " + results)
  }).catch(function(err) {
       console.log("error here: " + err);
  });
46
AntonB

いう

const util = require('util')
const fs_writeFile = util.promisify(fs.writeFile)

https://nodejs.org/api/util.html#util_util_promisify_original

これは、トップ投票の回答よりもバグが発生しにくい

43
amara

最後に、最新のnode.jsリリースv10.3.0はfs promiseをネイティブにサポートしています。

const fsPromises = require('fs').promises; // or require('fs/promises') in v10.0.0
fsPromises.writeFile(ASIN + '.json', JSON.stringify(results))
  .then(() => {
    console.log('JSON saved');
  })
  .catch(er => {
    console.log(er);
  });

詳細については、公式ドキュメントを確認してください。 https://nodejs.org/api/fs.html#fs_fs_promises_api

8
Lewis

Update2017年9月fs-promiseは廃止され、 fs-extra が採用されました。


使用していませんが、 fs-promise を調べることができます。以下のノードモジュールです。

すべての非同期fsメソッドをPromises/A +互換プロミスとして公開するプロキシ(when、Qなど)。すべての同期メソッドを値として渡します。

4
rouan
const util = require('util')
const fs = require('fs');

const fs_writeFile = util.promisify(fs.writeFile)

fs_writeFile('message.txt', 'Hello Node.js')
    .catch((error) => {
        console.log(error)
    });
2
Saeed Zarinfam

以下のように、try/catchブロック内でfs.writeFileSyncを使用します。

`var fs = require('fs');
 try {
     const file = fs.writeFileSync(ASIN + '.json', JSON.stringify(results))
     console.log("JSON saved");
     return results;
 } catch (error) {
   console.log(err);
  }`
0
Rahul Sadaphal