顺序承诺在Zapier触发器中



我有一个从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创建的东西,并将某些全球状态移至局部状态。

最新更新