为什么 .then() 在异步函数可以 return 之前声明 运行
Why does .then() statement run before the async function could return
我正在尝试使表单成为一个重复函数,它将允许我传入大多数函数并重新运行该函数 x 次,除非返回真值响应。
这里是这个想法的演示。
它有效,但它 returns 在 then 语句之后。
我认为问题在于异步中存在异步,即
异步 a( 异步 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>
如Evert所说,setInterval 需要是 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>
我正在尝试使表单成为一个重复函数,它将允许我传入大多数函数并重新运行该函数 x 次,除非返回真值响应。
这里是这个想法的演示。
它有效,但它 returns 在 then 语句之后。
我认为问题在于异步中存在异步,即
异步 a( 异步 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>
如Evert所说,setInterval 需要是 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>