我有一个从Web服务检索数据的Zapier触发器(App(。Web服务将数据返回500个项目的块,每个项目都包含UNIX TIMESTAMP和WEB服务参数('faster''(指定要检索的数据块的开始时间。
为了使此操作,我需要顺序检索数据块,在上一个块中检索的数据允许我找到下一个Web服务调用的" faster"值。
我目前正在使用的代码:
const fetchItems = (z, bundle, since) => {
return z.request({
url: URL_PATH + ':' + URL_PORT + '/v1/items',
params: {
since: since
}
}).then(( response) => {
if (response.status === 401) {
throw new Error('The authentication has expired.');
} else if (response.status !== 200){
throw new Error('Status ' + response.status + ' returned.');
}
return response.json;
});
};
const processItems = (z, bundle) => {
var jsonAll = [];
var since = 0;
var jsonLength = ITEM_BLOCK_SIZE;
return (function loop(i) {
if (jsonLength === ITEM_BLOCK_SIZE) {
new Promise((resolve, reject) => {
fetchTransactions(z, bundle, since).then((json) => {
since = json[json.length - 1].modified;
jsonLength = json.length;
for (j = 0; j < json.length; j++) {
jsonAll.push( json[j]);
}
resolve();
});
}).then(loop.bind(null, jsonLength));
} else {
return jsonAll;
}
})(0);
}
module.exports = {
...
operation: {
...
perform: processItems,
...
}
};
我遇到的问题是,当我运行此代码时,zapier返回以下错误:结果必须是一个数组,get:undefined,((
fetchitems((函数正常工作,它是返回指定的"自"值的数据块。
我的诺言经验有限,因此将不胜感激。
花了我一段时间来解开processItems
的意图,但是过了一会儿,我掌握了逻辑的悬而未决。我真的很感谢IIFE loop
逻辑的简单美,因此将其保留在我的版本中,但是您将一些假设混合在一起,以了解同步和异步代码的工作原理(这可能是由对承诺不熟悉的(。
const processItems = (z, bundle) => {
const jsonAll = [];
let since = 0;
return new Promise((resolve, reject) => {
(function loop() {
console.log("inLoop");
fetchTransactions(z, bundle, since)
.then(json => {
const jsonLength = json.length;
since = json[json.length - 1].modified;
jsonAll.push(...json);
if (jsonLength === ITEM_BLOCK_SIZE) {
loop(jsonLength);
} else {
resolve(jsonAll);
}
})
.catch(reject);
})();
});
};
// Testdriver (proves it works)
let callCount = 0;
const ITEM_BLOCK_SIZE = 10;
function fetchTransactions() {
return new Promise(resolve => {
if (callCount === 5) return resolve([{ modified: 100 }]);
const list = [];
for (let i = 0; i < ITEM_BLOCK_SIZE; i++) list.push({ modified: 42 });
callCount++;
resolve(list);
});
}
processItems({},{}).then(results =>
console.log(
"results are correct?",
results.length === 5 * ITEM_BLOCK_SIZE + 1
)
);
整体函数是 async 方法,而代码中的任何return
语句当然都是 synchronous 。这就是为什么它返回undefined
;返回的值将在函数体系执行后很长时间返回!
这就是Promise
S发光的地方。您可以从方法返回Promise
,然后等待稍后完成的承诺即可。这就是失败的:您基本上需要返回loop
功能内部resolve
D的承诺。
所以我补充说,删除了我认为是一些不必要的Promise
创建的东西,并将某些全球状态移至局部状态。