Javascript 承诺在节点模块内使用

Javascript 承诺在节点模块内使用,javascript,node.js,promise,bluebird,Javascript,Node.js,Promise,Bluebird,我对promise这个主题还不熟悉,我想知道我是否写了下面的代码 应该如此 我们正在项目中使用蓝鸟 代码如下: var start = function (destination ){ return new Promise(function (resolve, reject) { fs.readdir(destination, function (err, values) { if (err) { reject(er

我对promise这个主题还不熟悉,我想知道我是否写了下面的代码 应该如此

我们正在项目中使用蓝鸟

代码如下:

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();
                            }
                        });
                    }
                });
            }
        });

    });
};

在bluebird中,使用
newpromise
是一种反模式,应尽可能避免使用。相反,您可以使用bluebird的方法来
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;
        });
};
我会做你想做的,就像它应该做的那样


如果您使用的node早于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);
    });
};

在bluebird中,使用
newpromise
是一种反模式,应尽可能避免使用。相反,您可以使用bluebird的方法来
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;
        });
};
我会做你想做的,就像它应该做的那样


如果您使用的node早于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);
    });
};

放松点,老虎,你工作比你需要的更努力了

你的逻辑是:

  • 读取目标中的所有文件
  • 逆转
  • 保存最后一个文件,不要取消链接
  • 取消所有其他文件的链接
  • 以下是mmm使用和蓝鸟的替代答案:

    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}`));
    });
    

    放松点,老虎,你工作比你需要的更努力了

    你的逻辑是:

  • 读取目标中的所有文件
  • 逆转
  • 保存最后一个文件,不要取消链接
  • 取消所有其他文件的链接
  • 以下是mmm使用和蓝鸟的替代答案:

    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}`));
    });
    

    承诺只能被解析/拒绝一次-任何后续的解析/拒绝调用都将被忽略-您的代码有一个循环,每个循环将解析或拒绝承诺,除了第一个循环之外的任何内容都将被忽略(就承诺而言)-因此,不,您的代码不正确承诺只能被解析/拒绝一次-任何后续的解析/拒绝调用都将被忽略-您的代码有一个循环,每个循环将解析或拒绝承诺,除了第一个循环之外的任何内容都将被忽略(就承诺而言)-因此,不,您的代码不正确谢谢编辑@BenjaminGruenbaum!我们是否应该将代码中的
    .then(values=>values.reverse())
    更改为
    call(“reverse”)
    ?两者都可以,我认为这样很好。感谢@BenjaminGruenbaum的编辑!我们是否应该将代码中的
    .then(values=>values.reverse())
    更改为
    call(“reverse”)
    ?两者都可以,我认为这样很好。嗨,本杰明,谢谢!3个问题:)1。我使用bluebird版本2.9…所以我不认为我可以使用它“协同程序”(无法升级currenlty…)2。那么错误处理呢?3.我应该如何在旧版本的node(es5..)中使用它谢谢您的支持!1) 是的,你可以,2)在需要的时候捕获,这就像同步代码一样-它会在出错时传播到最近的
    。Catch
    (或者try/Catch-inside-coroutine)。3) 什么版本?如果高于0.10,您可以
    --和声发生器
    。嗨,本杰明,谢谢!3个问题:)1。我使用bluebird版本2.9…所以我不认为我可以使用它“协同程序”(无法升级currenlty…)2。那么错误处理呢?3.我应该如何在旧版本的node(es5..)中使用它谢谢您的支持!1) 是的,你可以,2)在需要的时候捕获,这就像同步代码一样-它会在出错时传播到最近的
    。Catch
    (或者try/Catch-inside-coroutine)。3) 什么版本?如果大于0.10,则可以
    --和声发生器