我有一系列函数,例如:
let funcs = []
funcs.push(() => {window.x = fetch()})
funcs.push(() => {console.log(window.x)})
funcs.push(() => {console.log("Hello, world!")})
我希望函数一个接一个被调用,如:
for (let func of funcs) {
func();
}
但是,我想将这些函数连接起来,就好像它们是 Promises 一样,以便仅在解析 N 函数时调用 N+1 函数。
根据 mdn 网络文档,
fetch()
将返回 Promise
,因此它将首先打印 Hello, world!
而不是 window.x
的值,因为 window.x
是 Promise
。因此,您必须先解决获取响应,然后再使用 async
函数打印它,如下所示:
let funcs = []
funcs.push(() => {
window.x = new Promise((resolve, reject) => {
fetch('https://dummyjson.com/carts/1')
.then(result => result.json())
.then(response => resolve(response))
.catch(error => reject(error));
});
});
funcs.push(async() => { console.log(await window.x) });
funcs.push(() => { console.log("Hello, world!") });
(async() => {
for (let func of funcs) {
await func();
}
})()
你的一些函数涉及异步操作,当你认为这样的函数“已解决”时,你必须明确。更准确地说,如果你想等待某个结果,你的函数必须返回对那个结果的承诺。例如,
fetch
返回响应对象的承诺:
funcs.push(() => {return window.x = fetch(...)});
但是您也可以等待响应主体被完全消耗:
funcs.push(() => {return window.x = fetch(...).then(r => r.text())});
像第二个和第三个这样的同步函数不需要返回任何东西。
有了它你可以使用下面的代码依次执行它们:
let promise = Promise.resolve();
for (const func of funcs) promise = promise.then(func);
您可以在
funcs
数组中将“正常”函数与返回承诺的函数混合使用,但您必须确保承诺(如果有的话......)实际上是生成函数的returned
,而不仅仅是产生。我删除了第一个函数周围的花括号({
,}
),并确保它在最后返回了一个“合理”的值(通过向它提供进一步的.then(r=>r.json()).then(d=>window.x=d.username)
)。
Once the
funcs
array is setup you can run the indivudual function consecutively in an async
function by using the await
keyword like this:
const url="https://jsonplaceholder.typicode.com/users/"; // public API for testing ...
let funcs = [
() => fetch(url+3).then(r=>r.json()).then(d=>window.x=d.username), // returns a promise
() => {console.log(window.x+` is the same as global x: ${x}`)}, // returns nothing
() => {console.log("Hello, world!")} ]; // returns nothing
async function doit(fns){ for (let fn of fns) await fn() }
doit(funcs);
使用像window.x
这样的全局变量通常
不是一个好主意。我只是将它包含在这里,以表明理论上您的方法可以发挥作用。但是,获得承诺结果的更好方法是通过最后一个链接的
then()
方法返回所需的值,并通过使用 await
等待它的表达式来获取它。但是,当然,那么您的第二个函数也需要更改,以便 not 与全局 x
一起工作,但具有给定的参数 val
:
const url="https://jsonplaceholder.typicode.com/users/"; // public API for testing ...
let funcs = [
() => fetch(url+3).then(r=>r.json()).then(d=>d.username), // returns a promise
(val) => {console.log(`This is val: ${val}`)}, // returns nothing
() => {console.log("Hello, world!")} ]; // returns nothing
async function doit(fns){
let v;
for (let fn of fns) v=await fn(v); // v gets re-evaluated each time!
}
doit(funcs);