使用setTimeout暂停其余的API调用

时间:2017-11-07 12:59:06

标签: javascript asynchronous async-await

我有一系列ID和一个需要调用的修复端点。所以我想预先知道ID数组,并为每个ID进行相应的rest API调用。由于我不想“淹没”端点,我想在每次呼叫之间等待一秒钟。另外,我想在使用新ID调用端点之前等待响应。

以下是我提出的建议:

// Code goes here
console.clear();

const url = 'some-domain.com/v1/api/users';
const ids = [1, 2, 3, 4, 5, 6, 7];
const serviceMock = (id) => new Promise((resolve, reject) => {

  console.log('Got request for id ' + id);
  setTimeout(() => {

    resolve(`${url}${id} returned ${ Math.floor((Math.random() * 100) + 1)}`);
  }, 2000);
});

const main = async() => {

  let index = 0;
  for (let id of ids) {

    index++;
    setTimeout(async() => {

      const data = await serviceMock(id);
      console.log(`Done for user ${id}!`);
      console.log(data);
    }, 1000 * index);
  }
};

main();

serviceMock中的setTimeout用于模拟其余的API调用,setTimeout中的main用于在调用之间暂停。

现在,我希望它的行为方式如下(在控制台中):

Got request for id 1
Done for user 1!
some-domain.com/v1/api/users1 returned 77
Got request for id 2
Done for user 2!
some-domain.com/v1/api/users2 returned 75
Got request for id 3
Done for user 3!
some-domain.com/v1/api/users3 returned 26
Got request for id 4
Done for user 4!
some-domain.com/v1/api/users4 returned 44
Got request for id 5
Done for user 5!
some-domain.com/v1/api/users5 returned 79
Got request for id 6
Done for user 6!
some-domain.com/v1/api/users6 returned 52
Got request for id 7
Done for user 7!
some-domain.com/v1/api/users7 returned 34

这就是我得到的:

Got request for id 1
Got request for id 2
Got request for id 3
Done for user 1!
some-domain.com/v1/api/users1 returned 77
Got request for id 4
Done for user 2!
some-domain.com/v1/api/users2 returned 75
Got request for id 5
Done for user 3!
some-domain.com/v1/api/users3 returned 26
Got request for id 6
Done for user 4!
some-domain.com/v1/api/users4 returned 44
Got request for id 7
Done for user 5!
some-domain.com/v1/api/users5 returned 79
Done for user 6!
some-domain.com/v1/api/users6 returned 52
Done for user 7!
some-domain.com/v1/api/users7 returned 34

以下是一个有效的例子:http://plnkr.co/edit/sNfk8GIfqbhrpql5hQ16?p=preview

我到底错过了什么?

2 个答案:

答案 0 :(得分:2)

不要在setTimeout中放置'await'。

我建议你写等待功能:

const wait = ms => new Promise(
  (resolve, reject) => setTimeout(resolve, ms)
);

现在您可以轻松输入:

const main = async () => {

  let index = 0;
  for (let id of ids) {
    index++;

    await wait(1000);

    const data = await serviceMock(id);
    console.log(`Done for user ${id}!`);
    console.log(data);
  }

};

main();

答案 1 :(得分:0)

一个简单的递归解决方案: 创建变量var i = 0以保存ID数组的当前索引。 接下来创建一个用于调用API的函数x()。在API调用的成功函数中,递增i,即ID数组的当前索引,然后检查i == array.length如果true,则在错误调用函数x()时不执行任何操作。