承诺在节点模块内使用

时间:2016-02-21 12:50:38

标签: javascript node.js promise bluebird

我是承诺主题的新手,我想知道我是否写下以下代码 应该如此。

我们正在项目中使用 bluebird

这是代码:

var start = function (destination ){
    return new Promise(function (resolve, reject) {
        fs.readdir(destination, function (err, values) {
            if (err) {
                reject(err);
            } else {
                values.reverse();
                var flag = true;
                values.forEach(function (file) {
                    if (flag) {
                        flag = false;
                        resolve();
                    } else {
                        fs.unlink(destination + '/' + file, function (err) {
                            if (err) {
                                console.log('Error ' + err);
                                reject(err);
                            } else {
                                console.log('sucess ' + dest + '/' + file);
                                resolve();
                            }
                        });
                    }
                });
            }
        });

    });
};

2 个答案:

答案 0 :(得分:1)

在bluebird中,使用new Promise是一种反模式,如果可能应该避免使用。相反,您可以将蓝鸟的promisifyAll()方法用于promisify fs,并将其作为起点。

例如:

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

var start = function (destination ) {
    return fs.readdirAsync(destination)
        .then(values => values.reverse()) // or `.call("reverse")`
        .then(values => {
            // your logic
        }); // .catch(err => { ... }); // by default bluebird logs errors to the console
};

在您的进一步逻辑中,您试图多次履行或拒绝承诺,这是无法完成的 - 只有第一次调用resolve/reject才会被考虑在内。我想你要删除除最新文件以外的所有文件。像

这样的东西
var start = function (destination ) {
    return fs.readdirAsync(destination)
        .then(values => values.reverse())
        .then(files => {
            files.shift();
            return files;
        })
        .map(file => fs.unlinkAsync(`${destination}/${file}`))
        .then(success => {
            console.log(success) // will hold an array of success messages
            return success;
        });
};

会做你想做的事,就像应该做的那样。

如果您使用的是早于v4的节点或者不熟悉es6,请参阅es5版本:

var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));

var start = function start(destination) {
    return fs.readdirAsync(destination).then(function (values) {
        return values.reverse();
    }).then(function (files) {
        files.shift();
        return files;
    }).map(function (file) {
        return fs.unlinkAsync(destination + '/' + file);
    }).catch(function (err) {
        console.log(err);
    });
};

答案 1 :(得分:1)

容易出现老虎,你的工作方式比你需要的更难。

你的逻辑是:

  1. 读取目的地中的所有文件
  2. 反转他们
  3. 保存最后一个文件,不要取消链接。
  4. 取消所有其他文件的链接
  5. 这是mmm使用coroutines和bluebird:

    的替代答案
    let Promise = require("bluebird");
    let fs = require("fs");
    Promise.promisifyAll("fs");
    
    const start = Promise.coroutine(function* (destination) { 
        let files = yield fs.readdirAsync(destination); // 1. read files
        files = files.reverse(); 2. reverse them
        files.shift(); // 3. except the first one
        yield Promise.map(files, f => fs.unlinkAsync(`${destination}/${f}`)); 4. unlink
    });
    

    或者,可能更优雅:

    const start = Promise.coroutine(function* (destination) { 
        let files = yield fs.readdirAsync(destination);
        files.pop();
        yield Promise.map(files, f => fs.unlinkAsync(`${destination}/${f}`));
    });