将异步/等待块中的部分代码提取到单独的函数中

问题描述 投票:0回答:2

我有一个异步匿名自调用函数。函数前面的“async”一词意味着该函数将始终返回一个承诺。如果代码中有 return,那么 JavaScript 会自动将其包装到具有该值的已解决的 Promise 中。

这个异步允许我们使用“等待”。关键字await 使JavaScript 等待,直到promise 解决并返回其结果。因此,函数执行会“暂停”,并在 Promise 解决时恢复。这不会消耗任何 CPU 资源,因为引擎可以同时执行其他工作:执行其他脚本、处理事件等。

(async () => {
    await page.goto('test.com', { waituntil: ['load', 'domcontentloaded', 'networkidle0'] });
    await page.evaluate((user, pass) => {
      document.querySelector('#user').setAttribute('value', user);
    }, user, pass)
    await page.click('button[type=submit].btn-primary');


    for(var i = 0; i < 10; i++){
        try { 
            await page.goto('test.com/second', { waituntil: ['load', 'domcontentloaded', 'networkidle0'] });
        } catch(e) {
                await page.goto('test.com', { waituntil: ['load', 'domcontentloaded', 'networkidle0'] });
                await page.evaluate((user, pass) => {
                    document.querySelector('#user').setAttribute('value', user);
                }, user, pass)
                await page.click('button[type=submit].btn-primary');
        } 

        // more stuff not relevant here
    }    

})();

但是正如您在上面看到的,我有重复的代码。我想将重复的代码提取到一个单独的函数中。像这样的东西:

(async () => {

    logIn()

    for(var i = 0; i < 10; i++){
        try { 
            await page.goto('test.com/second', { waituntil: ['load', 'domcontentloaded', 'networkidle0'] });
        } catch(e) {
            logIn()
        } 

        // more stuff not relevant here
    }    

})();


function logIn(){
                await page.goto('test.com', { waituntil: ['load', 'domcontentloaded', 'networkidle0'] });
                await page.evaluate((user, pass) => {
                    document.querySelector('#user').setAttribute('value', user);
                }, user, pass)
                await page.click('button[type=submit].btn-primary');
}

但是,这行不通,因为await 只能在aysnc 内工作。现在一个想法是将await 放在logIn 调用前面,如下所示:

await logIn()            

但事情是这样的。在该

logIn
函数中,我特意使用了 3 次 wait,因为我需要在下一个语句之前解决一个语句。

我怎样才能实现这个目标?使用 async/await 并使用我的登录功能?

javascript node.js asynchronous ecmascript-6
2个回答
0
投票

将您的

logIn
函数也设为异步函数:

async function logIn() {...}

然后,当你调用它时,

await

await logIn();

像这样:

async function logIn() {
  await page.goto('test.com', {
    waituntil: ['load', 'domcontentloaded', 'networkidle0']
  });
  await page.evaluate((user, pass) => {
    document.querySelector('#user').setAttribute('value', user);
  }, user, pass)
  await page.click('button[type=submit].btn-primary');
}

(async() => {
  await logIn();

  for (var i = 0; i < 10; i++) {
    try {
      await page.goto('test.com/second', {
        waituntil: ['load', 'domcontentloaded', 'networkidle0']
      });
    } catch (e) {
      logIn()
    }

    // more stuff not relevant here
  }
})();

有关异步函数的更多信息


0
投票

上面的解决方案还意味着调用登录的函数也需要是异步的,以及调用该函数的函数等等,一直到代码库的顶部。

本质上,在任何地方使用异步意味着所有函数都必须是异步的,并且所有函数都必须使用await调用。

我希望我们可以用await/async包装执行运算符,这样我们就不必将它传播到整个应用程序中。

我发现没有任何解决方案不涉及使所有函数异步并使用await 调用它们。

© www.soinside.com 2019 - 2024. All rights reserved.