簡體   English   中英

Node.js中的Promise.all不調用then函數

[英]Promise.all in Node.js doesn't call the then function

我學習了如何使用Node和Ecmascript 6。

我的腳本的目的是重命名目錄中的png文件列表。 我只想重命名png文件(假設還有jpg),並在最后顯示重命名的文件數。 由於Node的非阻塞性,它並不是那么明顯,我決定利用這次機會來發現ES6承諾。

'use strict';

const fs = require('fs-extra');

const dir = '/Users/toto/Desktop/png/';
const suffix = '_IMAGE.';
const regex = /(.*)\.(png)$/;
var nbFiles = 0;

// Rename a png file with a suffix
var renameFile = (filename) => {
  return new Promise((resolve, reject) => {
      if(regex.test(filename)){
        let newFileName = filename.replace(regex, '$1' + suffix + '$2');
        fs.rename(dir + filename, dir + newFileName, (err) => {
          let msg = filename + ' => ' + newFileName;

          if (err) {
            console.log('KO : rename of ' + msg);
            reject(err);
          }

          console.log('OK : rename of ' + msg); 
          resolve(nbFiles++);
        });
      }
    });
};

// Read files in a directory and call renameFile + display number of files renamed
fs.readdir(dir, (err, files) => {
    if(err) return console.error(err);

    var promise = Promise.all(
        files.map(renameFile)
    ).then(function(nb){
      console.log('Number of files renamed : ', nb);
    }).catch(function(err){
      console.log('Error ', err);
    });
});

預期的結果是要重命名文件並查看消息重命名文件數。

我將文件重命名,但是看不到任何消息(then或catch呼叫的消息)。 某處有問題,但是調試會話無法幫助我。

謝謝你的幫助!

PS:我的環境是Node 5.10和OS X 10.11。

問題是您正在創建一些承諾,這些承諾將永遠待定(永遠不會解決):當regexfilename不匹配時。 Promise.all將無限期地等待它們。

你應該總是promisify在盡可能低的水平-你的情況fs.renamefs.readdir -並把沒有其他的代碼,功能與“老”回調API涉及內。 沒有應用程序邏輯,沒有字符串連接,沒有日志記錄,什么都沒有。

function rename(from, to) {
    return new Promise((resolve, reject) => {
        fs.rename(from, to, (err, res) => {
            if (err) reject(err);
            else resolve(res);
        });
    });
}
function readdir(from, to) {
    return new Promise((resolve, reject) => {
        fs.readdir(from, to, (err, res) => {
            if (err) reject(err);
            else resolve(res);
        });
    });
}

(如果這看起來是重復的,那就是-編寫一個輔助函數,或使用Promise庫中的一個)

有了這些,您現在可以正確(並且更容易)實現腳本:

const dir = '/Users/toto/Desktop/png/';
const suffix = '_IMAGE.';
const regex = /(.*)\.(png)$/;
readdir(dir).then(files =>
    Promise.all(files.map(filename => ({
        from: dir + filename,
        to:   dir  + filename.replace(regex, '$1' + suffix + '$2')
    })).filter(r => r.from != r.to).map(r => {
        let msg = r.from + " => " + r.to;
        return rename(r.from, r.to).then(() => {
            console.log("OK: " + msg);
        }, err => {
            console.log("KO: " + msg);
            throw err;
        });
    }));
).then(function(res) {
    console.log('Number of files renamed : ', res.length);
}).catch(function(err) {
    console.error('Error ', err);
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM