Promise/then用于函数数组



我有一系列函数,例如:

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+1函数只有在解析N函数时才会被调用。

您的一些函数涉及异步操作,当您考虑这样的函数时必须明确"解决";。更确切地说,如果您想等待某个结果,那么您的函数必须返回该结果的promise。例如,fetch返回响应对象的promise:

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);

根据mdn web文档,fetch()将返回Promise,因此它将首先打印Hello, world!,而不是window.x的值,因为window.xPromise。因此,在使用async函数打印之前,您必须首先解析获取响应,如下所示:

let funcs = []
funcs.push(() => {
window.x = new Promise((resolve, reject) => {
fetch('https://dummyjson.com/carts/1')
.then(result => resolve(result.json()))
.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();
}
})()

您可以混合"正常的";函数,函数在funcs数组中返回promise,但您必须确保promise(如果有…)实际上是生成函数生成的returned,而不仅仅是生成的。我去掉了第一个函数周围的大括号({}),并确保它返回一个";明智的";值(通过向其提供另外的.then(r=>r.json()).then(d=>window.x=d.username))。

一旦设置了funcs数组,您就可以使用await关键字在async函数中连续运行单个函数,如下所示:

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这样的全局变量通常不是一个好主意。我把它放在这里只是为了表明理论上你的方法是可行的。然而,获得promise结果的更好方法是通过最后一个链接的then()方法返回所需的值,并通过用await等待它的表达式来获取它。但是,当然,您的第二个函数也需要更改,以便而不是使用全局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);

相关内容

  • 没有找到相关文章