【问题标题】:Why does .then() statement run before the async function could return为什么 .then() 语句在异步函数返回之前运行
【发布时间】:2021-09-20 19:55:45
【问题描述】:

我正在尝试使表单成为一个重复函数,它允许我传入大多数函数并重新运行该函数 x 次,除非返回真实响应。

这个想法的演示在这里。

它有效,但它返回 在 then 语句之后。

我认为问题在于异步中有异步,即

async a( async b( c ())

const repeatAttempts = async (func, args, attempts) => {
    try {
        let temp_interval = setInterval(function () {
            attempts -= 1;
            const function_response = func.apply(null, args)
            if (function_response) {
                console.log("function_response! = ", function_response);
                console.log("attempts! = ", attempts);
                clearInterval(temp_interval);
                return function_response
            }
            if (attempts < 1) {
                throw "Out of attempts"
            }

        }, 100);
    } catch (error) {
        console.error(error);
        return undefined;

    }
}




q = document.querySelector.bind(document)



repeatAttempts(q, ['dt'], 3).then((c) =>{console.log("then =",c)})
<div><dl>
  <dt><code>thisArg</code></dt>
  <dd>
    <p>The value of <code>this</code> provided for the call to <code>func</code>.</p>
    <p>Note that <code>this</code> may not be the actual value seen by the method: if the method is a function in <a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode">non-strict mode</a> code, <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null"><code>null</code></a> and <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined"><code>undefined</code></a> will be replaced with the global object, and primitive values will be boxed. This argument is required.</p>
  </dd>
  <dt><code>argsArray</code> <span class="badge inline optional">Optional</span></dt>
  <dd>
    <p>An array-like object, specifying the arguments with which <code>func</code> should be called, or <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null"><code>null</code></a> or <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined"><code>undefined</code></a> if no arguments should be provided to the function.</p>
    <p>Starting with ECMAScript 5 these arguments can be a generic array-like object instead of an array. See below for <a href="#browser_compatibility">browser compatibility</a> information.</p>
  </dd>
</dl></div>

【问题讨论】:

  • “它可以工作,但不能正确返回” - 所以,它不工作... -> “描述问题.“它不起作用”的描述性不足以帮助人们理解您的问题。相反,请告诉其他读者预期的行为应该是什么。告诉其他读者错误消息的确切措辞是什么,并且是哪一行代码产生的。”(来自How do I ask a good question?)
  • 稍后执行的是对setInterval 的回调,因为这正是它的目的。在setInterval 回调中抛出或返回也不会在这里做任何事情。您可以做的一件事是研究使用基于承诺的 setTimeout 版本。

标签: javascript asynchronous bind


【解决方案1】:

正如Evert 所说,setInterval 必须是基于 promise 的 setTimeout 版本。

感谢this 的回答,我们现在有了一个非常性感的功能。

const repeatAttempts = async (func, args, attempts) => {
    try {
        return waitUntil(func.apply(null, args), attempts)
    } catch (error) {
        console.error(error);
        return undefined;

    }
}


async function waitUntil(condition, left) {
  return await new Promise(resolve => {
    const interval = setInterval(() => {
      if (condition || left<1) {
        resolve(condition);
        clearInterval(interval);
      };left -=1;console.log(left)
    }, 100);
  });
}

q = document.querySelector.bind(document)



repeatAttempts(q, ['iframe'], 20).then((c) =>{console.log("then =",c)})
<div><dl>
  <dt><code>thisArg</code></dt>
  <dd>
    <p>The value of <code>this</code> provided for the call to <code>func</code>.</p>
    <p>Note that <code>this</code> may not be the actual value seen by the method: if the method is a function in <a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode">non-strict mode</a> code, <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null"><code>null</code></a> and <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined"><code>undefined</code></a> will be replaced with the global object, and primitive values will be boxed. This argument is required.</p>
  </dd>
  <dt><code>argsArray</code> <span class="badge inline optional">Optional</span></dt>
  <dd>
    <p>An array-like object, specifying the arguments with which <code>func</code> should be called, or <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/null"><code>null</code></a> or <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined"><code>undefined</code></a> if no arguments should be provided to the function.</p>
    <p>Starting with ECMAScript 5 these arguments can be a generic array-like object instead of an array. See below for <a href="#browser_compatibility">browser compatibility</a> information.</p>
  </dd>
</dl></div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多