javascript - Node JS : Array loop and function Not understanding how callbacks and promises work

标签 javascript node.js callback promise

回调和 promise 的新概念。我正在尝试读取正确返回地址的目录的内容,但此代码仅打印 console.log(value) 和函数 getAccount“gettin info ...”中的 console.log 但无处打印余额api 正在关闭并且进程已完成,我不明白这一点,因为正在传递地址并且第一个 console.log 正在函数内部打印但没有做进一步的工作。当我删除 fs.readdir 和 files.foreach 并将单个值传递给 getAccount 时,它工作得很好。没有错误或错误,它是一个运行时错误,我猜测与回调相关

'use strict';
const RippleAPI = require('ripple-lib').RippleAPI;
const testFolder = '/home/ripple/.keystore';
const fs = require('fs');
const api = new RippleAPI({server: 'wss://s1.ripple.com'});

function getAccount(address) {
        var balance = 0.0;
        console.log("getting info  for :"+address);
        return api.getAccountInfo(address).then(info => {
        var balance = info.xrpBalance;
        console.log("balance of "+address+" is "+balance);
        return balance;
        });
}

api.connect().then(() =>  {
        fs.readdir(testFolder, function(err, files) {
//      console.log("Total no of wallets : "+files.length);
//      for (var i =3000, len=3200; i < len; i++) {
//              var ad = files[i];
//              console.log(ad + "\t" + typeof(ad));
//              if(!xwallets.includes(ad))
                files.forEach(function(value) {
                        getAccount(value).then(balance => {console.log(balance); });
                        console.log(value);
                });
//              console.log("running for index : "+i+" filedata :"+files[i]);
//      }
        });
//      console.log(balance);
}).then(() => {
        return api.disconnect();
}).then(() => {
        console.log("done and disconnected");
}).catch(console.error);

最佳答案

您真的不想将返回 promise 的异步操作与接受直接回调的异步操作混合在一起。像这样混合时很难编写出良好的健壮代码。因此,由于您已经在许多操作中使用了 with promises,所以最好采用剩余的异步操作并“promisify”它们,以便您可以将它们与 promises 一起使用。然后,您可以利用所有干净的错误传播和 promise 链。

然后,其次,您必须确保循环中的所有异步操作都正确链接到父 Promise。为此,我们将循环中 getAccount() 的 promise 累积到一个 promise 数组中。然后,在循环之后,我们可以使用 Promise.all() 知道它们何时全部完成,然后从 readdir() 返回该 promise ,以便它们全部完成正确链接到父 promise 。

这将确保循环内的所有内容在父级解析之前和您调用 api.disconnect() 之前完成。

这是它的样子:

'use strict';
const RippleAPI = require('ripple-lib').RippleAPI;
const testFolder = '/home/ripple/.keystore';
const fs = require('fs');
const api = new RippleAPI({server: 'wss://s1.ripple.com'});

function getAccount(address) {
    var balance = 0.0;
    console.log("getting info  for :"+address);
    return api.getAccountInfo(address).then(info => {
        var balance = info.xrpBalance;
        console.log("balance of "+address+" is "+balance);
        return balance;
    });
}

// promisify readdir
const readdir = util.promisify(fs.readdir);

api.connect().then(() =>  {
    return readdir(testFolder).then(function(files) {
        const promises = [];
        files.forEach(function(file) {
            console.log(file);
            promises.push(getAccount(file).then(balance => {
                console.log(balance); 
                // make balance be the resolved value for this promise
                return balance;
            }));
        });
        // make sure we are waiting for all these promises to be done
        // by chaining them into the parent promise
        return Promise.all(promises);
    });
}).then(balances => {
    // process balances array here
    console.log(balances);
    return api.disconnect();
}, err => {
    // disconnect, even in the error case, but preserve the error
    console.error(err);
    return api.disconnect().then(() => {throw err;})
}).then(() => {
    console.log("done and disconnected");
});

所做更改的摘要:

  1. Promisify fs.readdir() 这样我们就可以使用 promise 了
  2. 改变我们调用 readdir() 的方式来使用 promises
  3. .forEach() 中的 getAccount() promises 收集到一个 promises 数组中
  4. 添加 return Promise.all(promises) 这样我们就可以等待所有这些 promise 完成,这样它就被链接到父 promise 中
  5. 使 balance 成为 .forEach() 循环中每个 promise 的解析值,即使在记录其值之后也是如此
  6. 确保即使在错误情况下我们也会调用 api.disconnect()
  7. 记录错误后,保留错误值作为拒绝原因

关于javascript - Node JS : Array loop and function Not understanding how callbacks and promises work,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48353448/

相关文章:

javascript - 在页面加载时将 aria-expanded ="true"更改为 false

javascript - 我应该对对 $.ajax 的调用进行单元测试还是对已发送的 XHR 进行单元测试?

javascript - joi_1.default.validate 不是函数

c++ - 在 openGL 中注册回调时出现编译错误

javascript - 在javascript中按下按钮时加载图像

javascript - 在 node.js 上托管具有 javascript 依赖项的 html

node.js - Express js - 无法重定向

javascript - js比较两个字符串

android - 如何使用 2 个字符串参数从 jni java 库调用?

javascript - 在新表单上使用 JavaScript 创建多个共享点项目,但延迟下一页加载,直到所有共享点项目都创建完成