【问题标题】:How to convert all this node code to promise如何将所有这些节点代码转换为承诺
【发布时间】:2015-08-02 16:47:23
【问题描述】:

我使用以下代码,我想将其转换为承诺,所以我已经开始承诺子进程,但我的问题是如何将所有转换为承诺, 我需要将代码划分为其他(参见 cmets)方法 当我按原样使用代码时,它的工作正常。

var Promise = require('bluebird'),
    fs = require('fs').


module.exports = {
    createNew: function () {
        fs.readFile("c://test.txt", 'utf8', function (err, data) {
            if (err) {
                return console.log(err);
            }

            // 1. from Here to needed to divide to new method
            //    which just return cmd value

            var fileKeyValObj = {};
            data.split("\n").forEach(function (element) {
                var sep = element.indexOf(':');

            });

            var cmd = fileKeyValObj['name'];

            // 2. this code should be in additional method

            if (typeof cmd !== 'undefined') {
                var exec = Promise.promisify(require('child_process').exec);
                var childProcess = exec(cmd).spread(function (stdout, stderr) {

                }).catch(function (error) {
                    console.log(error)
                });

            }
        });
    },
}

【问题讨论】:

  • 您要究竟做什么?你的代码写得不好,因此很难看到你的最终目标。
  • @royhowie- 你写的不好是什么意思?
  • 不清楚您要做什么。添加更多 cmets 来解释每个步骤。例如,您使用Promise.spread,但看起来cmd 是单个命令,而不是命令数组。

标签: javascript node.js promise bluebird


【解决方案1】:

您可以在 fs 上使用 bluebird .promisifyAll() 函数以及您的 exec 命令,然后将它们链接在一起:

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


var parseFile = function(data) {
  var fileKeyValObj = {};

  data.split('\n').forEach(function (element) {
      var sep = element.indexOf(':');
      var cmdValue = element.substring(sep + 2);
      fileKeyValObj[element.substr(3, sep)] = cmdValue;
  });

  return fileKeyValObj['name'];
};


module.exports = {
  createNew: function () {
    return fs.readFileAsync('c://test.txt', 'utf8')
      .then(parseFile)
      .then(exec)
      .spread(function(stdout, stderr) {
        // do stuff here with stdout and stderr

        if (stderr) {
          throw new Error('An Error Occurred.');
        }

        // anything returned will be returned on the next item in the chain.
        return stdout;
      });
    },
};

如何从另一个模块调用函数:

var myModule = require('./path/to/module');

myModule.createNew().then(function(data) {
  // this is the data returned from the final step of the createNew promise chain.
  console.log(data);
}).catch(function(err) {
  // catch and handle errors here instead.
  console.error(err);
});

【讨论】:

  • 谢谢 1+ 假设我想将以下内容放在不同的方法中,我应该如何使用它? data.split("\n").forEach(function (element) { var sep = element.indexOf(':'); var cmdValue = element.substring(sep + 2); fileKeyValObj[element.substr(3, sep )] = cmdValue; }); var cmd = fileKeyValObj['name'];
  • 几乎谢谢 :) 问题为什么你把下面的 ?var execCommand = function(cmd) { return exec(cmd); };
  • 2.你将如何处理错误,在这种情况下我不应该使用拒绝和解决?
  • 1.你的权利,它不是必需的,你可以将它直接传递给 exec 函数,它应该仍然可以工作。 2. 错误应该在最后的 catch 语句中被捕获。您可以通过使用 throw 抛出和错误来在 Promise 链中的任何位置引发错误。
  • 好的,谢谢,最后 2 个问题 :) 在我标记之前是一个答案?您将如何处理和错误(最佳实践) 2. 您将如何从其他模块调用此功能(createNew)并捕获异常(如果有),提前致谢!
【解决方案2】:

你应该在fs上使用Promise.promisifyAll

import Promise from 'bluebird'

let fs = Promise.promisifyAll(require('fs'))
let exec = Promise.promisify(require('child_process').exec)

function mapCommands (file) {
    return file.split('\n').reduce((p, c) => {
        let separation = c.indexOf(':')
        p[c.slice(3, separation)] = c.slice(separation + 2)
        return p
    }, {})    
}

function execCommands (obj) {
    let commands = []
    for (let key in obj) {
        let cmd = exec(obj[key])
        commands.push(cmd)
    }
    return Promise.all(commands)
}

export default {
    createNew () {
        fs.readFileAsync('C://test.txt', 'utf8')
        .then(mapCommands)
        .then(execCommands)
        .then(() => {
            // success; all commands executed
        }).catch((err) => {
            console.log(err)    // handle err
        }) 
    }
}

【讨论】:

  • 感谢 1+,我想测试代码是否应该使用其他库(Ecma 6)?
  • 我使用了一些 es6 语法,但您可以通过使用 function () {} 而不是 () => ()var Promise = require('bluebird')createNew: function () {} 轻松切换回 es5。如果你想让它“正常工作”,你可以使用babel.js
  • 在最后...(你把成功的地方)\
  • 我尝试这样做但没有成功,也许我应该使用一些 CO.. 模块?
猜你喜欢
  • 2016-01-08
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 2015-02-25
相关资源
最近更新 更多