我该如何写承诺链

时间:2019-01-25 18:07:46

标签: javascript

我有一些承诺:

getJson = new Promise((resolve, reject) => {
        $.getJSON(abiJson)
        .done(abi => {
            resolve(abi);
        })
        .fail(() => {
            reject('Eror loading ABI '+name);
        });
    });
    initWeb3 = () => {
        return new Promise((resolve, reject) => {
            (typeof web3 !== 'undefined') ?
            resolve(new Web3(web3.currentProvider)):
            reject('No find wallet, or web3 is undefined!');
        });
    }
    initContract = () => {
        return new Promise((resolve) => {
            resolve(web3.eth.contract(abi).at(address));
        });
    }
    initWallet = () => {
        return new Promise((resolve, reject) => {
            (window.web3.currentProvider.isMetaMask) ? resolve('Metamask') :
            (window.web3.currentProvider.isTrust) ? resolve('Trust') :
            (window.web3.currentProvider.constructor.name === 'EthereumProvider') ? resolve('Mist') :
            (window.web3.currentProvider.constructor.name === 'Web3FrameProvider') ?  resolve('Parity') :
            reject('Not suported wallet');
        });
    }
    initAccount = () => {
        return new Promise((resolve, reject) => {
            (typeof web3.eth.accounts[0] !== 'undefined') ?
            resolve(web3.eth.accounts[0]) :
            reject('Please login to the wallet');
        });
    }

帮我正确地写出承诺链。
首先,我需要getJson并将resolve写入一些var
然后我需要initWeb3()并将resolve写入一些var
然后initContract(),但是我需要从getJson获取abi并将其发送到initContract()并将resolve写入一些var
然后initWallet()并将resolve写入一些var
然后initAccount()并将resolve写入某些var
帮助我正确编写Promise链,并告诉我这是好的代码还是'shitcode'?

1 个答案:

答案 0 :(得分:0)

在您的情况下,您可以只使用 then(),因为除了开始时的第一个ajax请求外,您似乎并没有阻塞任务。

因此,您可以像这样直接进行操作:

getJson()
    .then(abi => {
      initWeb3();
      return abi;
     })
    .then(abi => {
      initContract();
      return abi;
     })
    .then(abi => {
      initWallet();
      return abi;
     })
    .then(initAccount) // you will find abi as the function argument
    .catch(e => console.error('something goes wrong', e));

别忘了在下巴末端使用 catch()方法,以获取在通话过程中可能引发的任何异常。

这种方式很脆弱,好像某个调用中出现了错误,其他所有调用都不会执行。

甚至调试也可能是一场噩梦。

我认为看一下您的代码,您可以通过以下方式做得更好:

    getJson()
        .then(abi => { // here you have the result
        try {
            initWeb3();
            initContract();
            initWallet();
            initAccount();
        } catch(e) {
            // do something here
        }
    })
    .catch(e => console.error('something goes wrong', e));

由于任何东西似乎都依赖于 initWeb3 ,因此应将所有内容置于try catch中。

这样,您就可以保证仅对ajax调用失败,并且当成功时,您只需执行自己的工作即可。

如果最后一部分有错误,则有更好的方法来处理。

通过这种方式,您可以使用ajax调用返回的 abi