5

を把握するために、 inQ.jsを使用して次のコードを変換したいと思います。基本的に、フォルダーが存在しない場合は作成し (mkdirp を使用)、ファイルをバックアップ フォルダーに移動し、ファイルをメイン フォルダーに保存します。async.seriesQ.js

var async = require('async');
var fs = require('fs');
var path = require('path');
var sessiondId = new Date().getTime() % 2 == 0 ? new Date().getTime().toString() : '_1234';
var backupFolder = path.join(__dirname,sessiondId);
var backupFullPath = path.join(backupFolder,'a.txt');
var fullPath = path.join(__dirname,'main','a.txt');
var mkdirp = require('mkdirp');

async.series({
    createOrSkip: function(callback) {
        mkdirp(backupFolder, function (err, dir) {
            if(err) {
                callback(err, null);
            } else {
                callback(null, {created: !!dir, folderAt: backupFolder});
            }
        }); 
    },
    move: function(callback) {
        fs.rename(fullPath, backupFullPath, function(err) {
            if(err) {
                callback(err, null);
            } else {
                callback(null, {backupAt: backupFullPath});
            }
        });
    },
    write: function(callback) {
        fs.writeFile(fullPath, 'abc', function(err) {
            if (err) {
                callback(err, null);
            } else {
                callback(null, {saveAt: fullPath});
            }
        });
    }
}, function(err, result) {
    console.log(result);
});

実際、どこから始めればよいかわかりません。ご協力いただきありがとうございます。

R.

4

2 に答える 2

10

重要なのは、開始する前に node.js 関数を変換して promise を使用Q.denodeifyすることです。これは、ファイルのヘッダーが次のようになることを意味します。

var Q = require('q')
var fs = require('fs');
var path = require('path');
var sessiondId = new Date().getTime() % 2 == 0 ? new Date().getTime().toString() : '_1234';
var backupFolder = path.join(__dirname,sessiondId);
var backupFullPath = path.join(backupFolder,'a.txt');
var fullPath = path.join(__dirname,'main','a.txt');

var mkdirp = Q.denodeify(require('mkdirp'));
var rename = Q.denodeify(fs.rename);
var writeFile = Q.denodeify(fs.writeFile);

node.js がプロミスをネイティブにサポートしている場合、その変更は必要ありません。

オプション1

// createOrSkip
mkdirp(backupFolder)
    .then(function (dir) {
        // move
        return rename(fullPath, backupFullPath);
    })
    .then(function () {
        // write
        return writeFile(fullPath, 'abc');
    })
    .done(function () {
        console.log('operation complete')
    });

それ以上に単純なことはないと思います。@Bergiが言ったように、それは「滝」に似ています。シリーズの正確な動作が必要な場合 (ただし、約束あり)、オプション 2 やオプション 3 などを使用する必要があります。

オプション 2

結果を保存するためにコードを手動で書き出すことができます。私は通常、これには少し余分な記述が必要ですが、はるかに読みやすいと思います。

var result = {}
mkdirp(backupFolder)
    .then(function (dir) {
        result.createOrSkip = {created: !!dir, folderAt: backupFolder};
        return rename(fullPath, backupFullPath);
    })
    .then(function () {
        result.move = {backupAt: backupFullPath};
        return writeFile(fullPath, 'abc');
    })
    .then(function () {
        result.write = {saveAt: fullPath};
        return result;
    })
    .done(function (result) {
        console.log(result);
    });

オプション 3

この種のコードを常に使用している場合は、非常に単純なシリーズ ヘルパーを作成できます (個人的にこれを行う必要があるとは思いませんでした)。

function promiseSeries(series) {
    var ready = Q(null);
    var result = {};
    Object.keys(series)
        .forEach(function (key) {
            ready = ready.then(function () {
                return series[key]();
            }).then(function (res) {
                result[key] = res;
            });
        });
    return ready.then(function () {
        return result;
    });
}
promiseSeries({
    createOrSkip: function () {
        return mkdirp(backupFolder).then(function (dir) {
            return {created: !!dir, folderAt: backupFolder};
        });
    },
    move: function () {
        return rename(fullPath, backupFullPath)
            .thenResolve({backupAt: backupFullPath});
    },
    write: function () {
        return writeFile(fullPath, 'abc')
            .thenResolve({saveAt: fullPath});
    }
}).done(function (result) {
    console.log(result);
});

ヘルパーを作成すると、コードは、コールバックを操作するために必要なすべてのエラー処理作業よりも、promise の方がはるかに明確になります。手で書いたり、これらの中間結果をすべて追跡しない場合は、さらに明確になると思います。

まとめ

async.seriesこれらの例は、バージョンよりも明確であると思うかもしれませんし、そうでないかもしれません。ただし、その機能をどれだけよく知っているかを検討してください。実際には、非常に不透明な方法でかなり複雑なことを行っています。私は当初、最後の結果のみが返されると想定しており (ala waterfall)、Async のドキュメントで調べる必要がありました。Promise ライブラリのドキュメントを調べる必要はほとんどありません。

于 2013-08-29T15:39:15.000 に答える