我是JS新手,我不理解我在代码片段中看到的行为

const task1 = new Promise((res, rej) => {
  setTimeout(() => res('one'), 5000)
})

const task2 = new Promise((res, rej) => {
  setTimeout(() => res('two'), 5000)
})

task1
.then((x) => {                    // first then
    return Promise.resolve(task2)
})
.then((res) => {console.log(res)}) // expect to log after 10 seconds, but logs after 5 seconds

async function test() {
  try {
    const res = await task1;
    const res2 = await task2;
    console.log(res2); // also logs after 5 seconds
  } catch (error) {
    console.error(`error`);
  }
}

test();

我的理解是,第一个".Then"仅在任务1在5秒后解析后触发,然后任务2在另一个5秒后启动并解析.然而,控制台在5秒后记录,而不是10秒.我哪里出错了?

推荐答案

通过将promise 创建为new Promise,您可以立即执行它们,因此它们是独立的,不会形成任何类型的队列.

要解决这个问题,您应该将任务作为函数并在队列中调用它们(当一个函数返回的promise 被解析时,调用下一个函数).

要运行下一个函数,你应该在前一个函数的.then()以内调用它.

你也可以把你的任务放到一个数组中,然后在一个for..of循环中调用.

为了更好地发挥作用,您可以使用异步生成器函数将promise 数组创建函数转换为异步生成器,然后使用for await在队列中迭代您的promise .

<script type="module">

const task1 = () => new Promise((res, rej) => {
  setTimeout(() => res('one'), 1000)
})

const task2 = () => new Promise((res, rej) => {
  setTimeout(() => res('two'), 1000)
})

async function* queue(arr){
  for(const fn of arr){
    yield await fn();    
  }
}

// using then
await task1().then(result => (console.log(result), task2().then(result => console.log(result))));

// using await
console.log(await task1());
console.log(await task2());

// using an array
for (const task of [task1, task2]){
  console.log(await task());
}

// using async generator
for await(const result of queue([task1, task2])){
  console.log(result);
}
</script>

Javascript相关问答推荐

将状态向下传递给映射的子元素

我应该绑定不影响状态的函数吗?'

如何强制Sphinx中的自定义js/css文件始终加载更改而不缓存?

当id匹配时对属性值求和并使用JavaScript返回结果

在开发期间,Web浏览器如何运行&qot;.jsx&qot;文件?

TinyMCE 6导致Data:Image对象通过提供的脚本过度上载

搜索功能不是在分页的每一页上进行搜索

回溯替代方式

每次重新呈现时调用useState initialValue函数

删除元素属性或样式属性的首选方法

Node.js错误: node 不可单击或不是元素

如何在TransformControls模式下只保留箭头进行翻译?

在ChartJS中使用spanGaps时,是否获取空值的坐标?

如何正确地在ComponentWillUnmount中卸载状态以避免内存泄漏?

如何将字符串拆分成单词并跟踪每个单词的索引(在原始字符串中)?

如何使用Cypress在IFRAME中打字

递增/递减按钮React.js/Redux

如何在加载页面时使锚定标记成为焦点

在点击链接后重定向至url之前暂停

如何从Reaction-Redux中来自API调用的数据中筛选值