簡體   English   中英

bluebird - 函數返回promise對象而不是實際數據

[英]bluebird - function returns promise objects instead of actual data

這個片段之后,我試圖編寫一個循環通過目錄,查找目錄,並從這些目錄中讀取xml文件名的函數(我知道文件夾結構將始終保持不變)。 到目前為止,我的函數正在按預期工作,但是當我嘗試從函數返回時,我只得到Promise對象。

我的代碼:

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

function getFileNames(rootPath) {
  // Read content of path
  return fs.readdirAsync(rootPath)
    // For every file in path
    .then(function(directories) {
      // Filter out the directories
      return directories.filter(function(file) {
        return fs.statSync(path.join(rootPath, file)).isDirectory();
      });
    })
    // For every directory
    .then(function(directories) {
      return directories.map(function(directory) {
        // Read file in the directory
        return fs.readdirAsync(path.join(rootPath, directory))
          .filter(function(file) {
            return path.extname(file) == '.XML';
          })
          .then(function(files) {
            // Do something with the files
            return files;
          });
        });
    });
}

getFileNames('./XML').then(function(files) {
  console.log(files);
});

當我console.log(files)最后的內部.then內部功能getFileNames ,我得到的文件名的實際陣列控制台。 但是當我運行上面的代碼時,我得到了這個輸出:

[ Promise {
    _bitField: 0,
    _fulfillmentHandler0: undefined,
    _rejectionHandler0: undefined,
    _promise0: undefined,
    _receiver0: undefined },
  Promise {
    _bitField: 0,
    _fulfillmentHandler0: undefined,
    _rejectionHandler0: undefined,
    _promise0: undefined,
    _receiver0: undefined },
  Promise {
    _bitField: 0,
    _fulfillmentHandler0: undefined,
    _rejectionHandler0: undefined,
    _promise0: undefined,
    _receiver0: undefined },
  Promise {
    _bitField: 0,
    _fulfillmentHandler0: undefined,
    _rejectionHandler0: undefined,
    _promise0: undefined,
    _receiver0: undefined },
  Promise {
    _bitField: 0,
    _fulfillmentHandler0: undefined,
    _rejectionHandler0: undefined,
    _promise0: undefined,
    _receiver0: undefined } ]

為什么會發生這種情況以及如何解決?

在線

.then(function(directories) {
  return directories.map(function(directory) {
    return fs.readdirAsync…

你正在為一系列承諾創造一個承諾,而這正是你在最終日志中得到的。 而不是返回一個promises數組,你需要返回一個值數組的promise - 而Promise.all正是這樣做的:

.then(function(directories) {
  return Promise.all(directories.map(function(directory) {
    return fs.readdirAsync(…)
    …
  }));
})

但是,在Bluebird中,使用Promise.map(directories, function(…) { … })甚至map方法 (類似於你已經使用.filter對每個目錄中的文件.filter那樣Promise.map(directories, function(…) { … })會更加慣用:

function getFileNames(rootPath) {
  return fs.readdirAsync(rootPath)
  .filter(function(file) {
    return fs.statAsync(path.join(rootPath, file)).then(function(s) {
      return s.isDirectory();
    });
  })
  .map(function(directory) {
//^^^^
    return fs.readdirAsync(path.join(rootPath, directory))
    .filter(function(file) {
      return path.extname(file) == '.XML';
    })
    .map(function(file) {
      // Do something with every file
      return file;
    });
  });
}

試試這個

return getFileNames('./XML').then(function(files) {
    console.log(files);
    return files;
});

這段代碼:

.then(function(directories) {
   return directories.map(function(directory) {
     return fs.readdirAsync(path.join(rootPath, directory))
     ...

將返回一個promises數組到當時的回調。 Promise數組在此處計為立即值,不會與數組的Promise相關聯。 要將Promise.all數組轉換為數組的promise,可以使用Promise.all ,但是由於您使用的是bluebird,因此您有更好的選擇:

您所要做的就是使用Promise.map

.then(function(directories) {
   return Promise.map(directories, function(directory) {
     return fs.readdirAsync(path.join(rootPath, directory))
     ...

弄清楚,第二個函數有一個。然后太多了:

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

function getFileNames(rootPath) {
  // Read content of path
  return fs.readdirAsync(rootPath)
      .then(function(content) {
        return content.filter(function(file) {
          return fs.statSync(path.join(rootPath, file)).isDirectory();
        });
      })
      // For every directory
      .map(function(directory) {
        // Read files in the directory
        return fs.readdirAsync(path.join(rootPath, directory))
            .filter(function(file) {
              return path.extname(file) == '.XML';
            });
      });
}

getFileNames('./XML').then(function(files) {
  console.log(files);
});

暫無
暫無

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

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