nodejs 如何同步执行代码并获取返回值

ztj1993
  • 56

我有异步代码段,这段代码其实是 new Promise() 的对象,但是我需要多次循环这个对象同时获取其中的值,代码如下:

module.exports = function (options) {
    var nodegit = require("nodegit");
    var configs = [
        {
            "path": "path1",
            "branch": ""
        },
        {
            "path": "path2",
            "branch": ""
        }
    ];
    for (var i = 0; i < configs.length; i++) {
        nodegit.Repository.open(configs[i].path).then(function (repo) {
            return repo.getCurrentBranch();
        }).then(function (reference) {
            configs[i].branch = reference.name();
            return reference;
        });
    }
    console.log(configs);
};

上面的代码的意思是根据configs.path来更新configs.branch;但是 nodegit 使用的是 Promise 同步执行模式,请问我如何能获取 Promise.then 的数据,或者上面的代码如何修改比较合适?谢谢!

难道我需要通过循环一层一层的 then 下去?

回复
阅读 5.5k
4 个回答
cnwhy
  • 916
✓ 已被采纳

你的代码没什么大问题,主要是第二个configs[i]用错了,再了解一下Promise.all就知道怎么写了;
参考代码:

module.exports = function (options) {
    var nodegit = require("nodegit");
    var configs = [
        {
            "path": "path1",
            "branch": ""
        },
        {
            "path": "path2",
            "branch": ""
        }
    ];
    
    var getBranch = function(path){
        return nodegit.Repository.open(path).then(function (repo) {
            return repo.getCurrentBranch();
        })
    }
    
    var promises = configs.map(v=>{
        return getBranch(v.path).then(reference=>{
            v.branch = reference.name();
            return v;
        })
    })

    return Promise.all(promises)
};

@unicreators 的效率会差一点
@RandyO 的代码和我的代码意思差不多,只是那个All应该是小写

async/await是好东西,但建议先完全搞清楚Promise再使用.

使用 es6 async/await

var nodegit = require("nodegit");
module.exports = async function (paths) {        
    let result = [];
    for (var i = 0; i < paths.length; i++) {
        let repo = await nodegit.Repository.open(paths[i]);
        let reference = await repo.getCurrentBranch();        
        result.push({ path: paths[i], reference, branch: reference.name() });
    }    
    return result;    
};

使用await调用

let result = await require('...')(['path1','path2', 'pathN']);
// or 
require('...')(['path1','path2', 'pathN']).then(result){
    // ...
}
var nodegit = require("nodegit");
module.exports = async function(options) {
    var configs = [{
        "path": "path1",
        "branch": ""
    }, {
        "path": "path2",
        "branch": ""
    }];
    var promises = []
    for (let i = 0; i < configs.length; i++) {
        promises.push(nodegit.Repository.open(configs[i].path));
    }

    const repos = await Promise.All(promises);

    for (let i = 0; i < configs.length; i++) {
        let reference  = await repos[i].getCurrentBranch();
        configs[i].branch = reference.name();
    }

    console.log(configs);
}

谢谢大神们的回复。这个问题基本上是按照我原来的写法思路实现的,具体见 unicreators 下的评论。解决方案上是使用 Promise.all 实现。同时原则上如果不需要 return ,不要使用 async/await。

宣传栏