簡體   English   中英

如何使用 Promise 重寫函數?

[英]How do I rewrite a function using promises?

我是節點 js 的新手。 我的任務是按擴展名查找文件。 我寫了一個遞歸函數,它按擴展名搜索文件,但不能將結果寫入數組。 說你需要使用 Promise 重寫函數,但我不知道該怎么做

var fs = require('fs'); 
var path = require('path'); 
var pathSupplied = './';
var extFilter = 'js';
function extension(element) {
    var extName = path.extname(element);
    return extName === '.' + extFilter;
};

let result = []

let walk = function (dir) {
    fs.readdir(dir, function (err, list) {
        list.forEach((item) => {
            let itemPath = path.join(dir, item);
            fs.stat(itemPath, (e, stats) => {
                if (stats.isDirectory()) {
                    walk(itemPath);
                } else {
                    if(extension(itemPath)){
                        console.log(itemPath)
                        result.push(itemPath)
                    }
                }
            });
        });
    })
}
walk(pathSupplied)
console.log(result)

以下是您如何做出承諾:

你通常會有回調的地方:

fs.readdir(dir, function (err, list) => {}

您可以編寫自己的函數,看起來像這樣

function readdirP(dir) {
  return new Promise((resolve, reject) => {
    fs.readdir(dir, (err, list) => {
      if (err) reject(err);
      resolve(list);
    })
  })
}

npm 包 fs-extra 已經為您完成了這項工作。

您可以執行以下操作以在此上下文中使用承諾,我建議使用 promisify 將基於回調的函數轉換為返回承諾的函數。 這可以節省您為每一個編寫樣板代碼:

const fs = require('fs'); 
const path = require('path');
const pathSupplied = './';
const extFilter = 'js';
const { promisify } = require('util');
const readdirPromise = promisify(fs.readdir);
const statPromise = promisify(fs.stat);

function extension(element) {
    var extName = path.extname(element);
    return extName === '.' + extFilter;
};

async function walk(dir, result = []) {
    let list = await readdirPromise(dir);
    for(let item of list) {
        let itemPath = path.join(dir, item);
        let stats = await statPromise(itemPath)
        if (stats.isDirectory()) {
            walk(itemPath, result);
        } else {
            if(extension(itemPath)){
                result.push(itemPath)
            }
        }
    }

    return result;
}

async function testWalk() {
    let result = await walk(pathSupplied)
    console.log("Result:", result);
}

testWalk();

試試這個你可以在沒有承諾的情況下解決這個問題

const fs = require('fs');  

const folderPath = __filename.replace('index.js', '');

fs.readdir(folderPath, function (err, items) {
for (var i = 0; i < items.length; i++) {
    if (items[i] !== 'index.js') {
        var checkJsFile = items[i].match(/\.(js|jsx)$/) != null;
        if (checkJsFile) {
            var item = items[i].replace('.js', '');
            router.use(require('./' + item));
        }
    }
}
});

module.exports = router;

您需要先了解為什么會遇到此問題,您正在調用async 函數,然后直接調用 console.log,這將在 asyn 函數完成之前顯示輸出

您可以通過以下兩種方式之一解決此問題

  1. 稍后使用承諾或回調對結果采取行動

  2. 調用同步版本的方法 ——https://nodejs.org/api/fs.html#fs_fs_readdirsync_path_options

    const 結果 = fs.readdirSync(path)

希望有幫助

你可以考慮下面的承諾代碼:

var fs = require('fs'); 
var path = require('path'); 
var extFilter = 'js';

function extension(element) {
    var extName = path.extname(element);
    return extName === '.' + extFilter;
};

let pathList = [];

const readDirectory = dir => new Promise((resolve,reject) => {
    fs.readdir(dir, function (err, list) {
        if(err !== null){
            reject(err.message);
        }
        addPath(list,dir)
        .then(()=>{
            console.log(pathList);
        })
        .catch((err)=>{
            reject(err.message);
        })
    });
});

const addPath = (list,dir) => new Promise((resolve,reject) => {
    for (let i = 0; i < list.length; i++) {
        let itemPath = path.join(dir, list[i]);
        fs.stat(itemPath, function (err, stats) {
            if(err !== null){
                reject(err);
            }
            else if (stats.isDirectory()) {
                readDirectory(itemPath);
            } else {
                if(extension(itemPath)){
                    pathList.push(itemPath);
                }
            }

            if(i === list.length-1){
                resolve();
            }
        });
    }
});

readDirectory("C://Users//Default//Desktop//New folder")
.then((items) =>{
    console.log(items.toString());
})
.catch((msg)=>{
    console.log(msg);
})

暫無
暫無

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

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