全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页

JS异步进阶与并发控制测试

20 题 45 分钟 难度:

考察知识点

  • 异步迭代器与for await...of:掌握异步迭代器协议及异步遍历语法
  • Generator函数与异步生成器:理解Generator函数特性及其在异步编程中的应用
  • Promise高级方法:深入理解Promise.all、Promise.race、Promise.allSettled的差异与应用场景
  • 并发控制模式:掌握并发限制、批量请求处理等实用技巧
  • 异步错误处理:理解异步场景下的错误捕获与处理策略
1
单选题

以下代码的输出结果是什么?

JavaScript
async function* asyncGenerator() {
    yield Promise.resolve(1);
    yield Promise.resolve(2);
    yield Promise.resolve(3);
}

(async () => {
    for await (const value of asyncGenerator()) {
        console.log(value);
    }
})();
A

1, 2, 3 依次输出

B

Promise {1}, Promise {2}, Promise {3} 依次输出

C

undefined 输出三次

D

报错:asyncGenerator 不是可迭代对象

2
多选题

关于异步迭代器和 for await...of,以下说法正确的有哪些?

A

异步迭代器必须实现 [Symbol.asyncIterator]() 方法

B

普通迭代器(实现 [Symbol.iterator]())也可以用于 for await...of

C

异步迭代器的 next() 方法必须返回 Promise<{value, done}>

D

for await...of 只能在 async 函数或模块顶层使用

E

Node.js 的可读流默认实现了异步迭代器接口

3
单选题

以下代码的输出结果是什么?

JavaScript
async function* asyncGen() {
    yield 1;
    throw new Error('generator error');
    yield 2;
}

(async () => {
    try {
        for await (const val of asyncGen()) {
            console.log(val);
            if (val === 1) break;
        }
    } catch (e) {
        console.log('caught:', e.message);
    }
})();
A

1, 然后 caught: generator error

B

1, 然后 caught: generator error, 再输出 2

C

只输出 1

D

报错,break 不能用于 for await...of

4
判断题

对象可以同时实现 [Symbol.iterator]()[Symbol.asyncIterator](),使其既支持 for...of 又支持 for await...of

A

B

5
填空题

请填写异步迭代器的完整实现:

JavaScript
const asyncRange = {
    from: 1,
    to: 5,

    [!!1!!]() {
        return {
            current: this.from,
            last: this.to,

            async !!2!!() {
                if (this.current <= this.last) {
                    await new Promise(resolve => setTimeout(resolve, 100));
                    return { !!3!!: this.current++, !!4!!: false };
                } else {
                    return { !!5!!: true };
                }
            }
        };
    }
};
6
单选题

以下代码的输出结果是什么?

JavaScript
function* generator() {
    const x = yield 1;
    const y = yield x + 2;
    return y + 3;
}

const gen = generator();
console.log(gen.next());
console.log(gen.next(10));
console.log(gen.next(20));
A

{value: 1, done: false}, {value: 12, done: false}, {value: 23, done: true}

B

{value: 1, done: false}, {value: 2, done: false}, {value: 3, done: true}

C

{value: undefined, done: false}, {value: 12, done: false}, {value: 23, done: true}

D

{value: 1, done: false}, {value: 10, done: false}, {value: 20, done: true}

7
单选题

以下代码的输出结果是什么?

JavaScript
function* gen() {
    try {
        yield 1;
        yield 2;
        yield 3;
    } finally {
        console.log('cleanup');
    }
}

const g = gen();
console.log(g.next());
console.log(g.return(100));
console.log(g.next());
A

{value:1,done:false}, {value:100,done:true}, cleanup输出, {value:undefined,done:true}

B

{value:1,done:false}, cleanup输出, {value:100,done:true}, {value:undefined,done:true}

C

{value:1,done:false}, {value:100,done:true}, {value:undefined,done:true}

D

{value:1,done:false}, cleanup输出, {value:100,done:true}, cleanup输出

8
多选题

关于 Generator 函数,以下说法正确的有哪些?

A

Generator 函数通过 function* 定义,返回一个 Generator 对象

B

yield 只能在 Generator 函数内部直接使用,不能在嵌套的普通函数中使用

C

Generator 对象既是迭代器又是可迭代对象

D

yield* 可以用于委托给另一个 Generator 或可迭代对象

E

async Generator 函数(async function*)返回的是异步迭代器

9
单选题

以下代码的输出结果是什么?

JavaScript
async function* fetchPages(urls) {
    for (const url of urls) {
        const response = await fetch(url);
        const data = await response.json();
        yield data;
    }
}

const urls = ['url1', 'url2', 'url3'];
const gen = fetchPages(urls);

// 假设每个请求返回 { page: 1 }, { page: 2 }, { page: 3 }
(async () => {
    for await (const data of gen) {
        console.log(data.page);
    }
})();
A

1, 2, 3 依次输出

B

Promise 对象依次输出

C

undefined 输出三次

D

报错:async Generator 不能用于 for await...of

10
判断题

Generator 函数不能作为构造函数使用,不能通过 new 关键字调用。

A

B

11
判断题

Generator 对象一旦迭代完成(done 为 true),就不能再次从头开始迭代。

A

B

12
单选题

以下关于 Web Worker 的说法,哪一项是错误的?

A

Web Worker 在独立的线程中运行,不阻塞主线程

B

Web Worker 不能直接访问 DOM 元素

C

Web Worker 可以通过 postMessage 与主线程通信

D

Web Worker 可以直接操作主线程的全局变量

E

Web Worker 可以使用 XMLHttpRequest 或 fetch 进行网络请求

13
单选题

以下代码实现了一个简单的 Worker 线程池,请问 createTask 函数的实现思路是什么?

JavaScript
class WorkerPool {
    constructor(numWorkers) {
        this.workers = [];
        this.taskQueue = [];
        this.activeTasks = new Map();

        for (let i = 0; i < numWorkers; i++) {
            const worker = new Worker('worker.js');
            worker.id = i;
            worker.busy = false;
            this.workers.push(worker);
        }
    }

    runTask(data) {
        const availableWorker = this.workers.find(w => !w.busy);
        if (availableWorker) {
            return this.executeOn(availableWorker, data);
        } else {
            return new Promise(resolve => {
                this.taskQueue.push({ data, resolve });
            });
        }
    }

    executeOn(worker, data) {
        worker.busy = true;
        return new Promise(resolve => {
            const taskId = Date.now() + Math.random();
            this.activeTasks.set(taskId, resolve);
            worker.postMessage({ taskId, data });
        });
    }

    handleResult(worker, taskId, result) {
        const resolve = this.activeTasks.get(taskId);
        if (resolve) {
            resolve(result);
            this.activeTasks.delete(taskId);
        }
        worker.busy = false;
        if (this.taskQueue.length > 0) {
            const next = this.taskQueue.shift();
            this.executeOn(worker, next.data).then(next.resolve);
        }
    }
}
A

当所有 Worker 都忙碌时,任务会被拒绝执行

B

任务完成后,Worker 会自动处理队列中的下一个任务

C

每个 Worker 只能处理一个任务然后就被销毁

D

所有任务必须等待所有 Worker 完成后才能执行

14
多选题

关于 Web Worker 与主线程之间的数据传输,以下说法正确的有哪些?

A

postMessage 传输的数据会被结构化克隆,不是直接共享引用

B

使用 Transferable 对象传输时,原线程会失去对该对象的访问权

C

SharedArrayBuffer 可以实现主线程与 Worker 之间的零拷贝数据共享

D

ArrayBuffer、MessagePort、ImageBitmap 是可转移对象

E

Worker 可以通过 importScripts 加载外部脚本

15
单选题

以下代码实现了一个简单的 Worker 线程池,请问 Worker 完成任务后会发生什么?

JavaScript
class WorkerPool {
    constructor(numWorkers) {
        this.workers = [];
        this.taskQueue = [];
        this.activeTasks = new Map();

        for (let i = 0; i < numWorkers; i++) {
            const worker = new Worker('worker.js');
            worker.busy = false;
            this.workers.push(worker);
        }
    }

    runTask(data) {
        const availableWorker = this.workers.find(w => !w.busy);
        if (availableWorker) {
            return this.executeOn(availableWorker, data);
        } else {
            return new Promise(resolve => {
                this.taskQueue.push({ data, resolve });
            });
        }
    }

    executeOn(worker, data) {
        worker.busy = true;
        return new Promise(resolve => {
            const taskId = Date.now() + Math.random();
            this.activeTasks.set(taskId, resolve);
            worker.postMessage({ taskId, data });
        });
    }

    handleResult(worker, taskId, result) {
        const resolve = this.activeTasks.get(taskId);
        if (resolve) {
            resolve(result);
            this.activeTasks.delete(taskId);
        }
        worker.busy = false;
        if (this.taskQueue.length > 0) {
            const next = this.taskQueue.shift();
            this.executeOn(worker, next.data).then(next.resolve);
        }
    }
}
A

Worker 完成任务后被销毁,不再可用

B

Worker 完成任务后变为空闲状态,自动处理队列中的下一个任务

C

所有 Worker 必须等待队列清空才能继续处理

D

任务队列中的任务会被丢弃

16
判断题

调用 worker.terminate() 会立即终止 Worker 线程,Worker 内部无法阻止或感知这一终止操作。

A

B

17
单选题

以下代码的输出顺序是什么?

JavaScript
console.log('1');

setTimeout(() => console.log('2'), 0);

Promise.resolve()
    .then(() => console.log('3'))
    .then(() => console.log('4'));

console.log('5');
A

1, 5, 3, 4, 2

B

1, 5, 2, 3, 4

C

1, 2, 3, 4, 5

D

1, 5, 3, 2, 4

18
单选题

以下代码的输出顺序是什么?

JavaScript
console.log('start');

setTimeout(() => {
    console.log('timeout');
    Promise.resolve().then(() => console.log('timeout promise'));
}, 0);

Promise.resolve()
    .then(() => {
        console.log('promise1');
        setTimeout(() => console.log('promise timeout'), 0);
    })
    .then(() => console.log('promise2'));

console.log('end');
A

start, end, promise1, promise2, timeout, timeout promise, promise timeout

B

start, end, promise1, timeout, promise2, timeout promise, promise timeout

C

start, end, promise1, promise2, timeout, promise timeout, timeout promise

D

start, end, timeout, promise1, promise2, timeout promise, promise timeout

19
判断题

每个宏任务执行完毕后,事件循环会立即执行所有已排队的微任务,直到微任务队列清空。

A

B

20
单选题

以下代码的输出结果是什么?

JavaScript
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.reject('error');

Promise.all([p1, p2, p3])
    .then(results => console.log('success:', results))
    .catch(error => console.log('error:', error));

Promise.all([p1, p2])
    .then(results => console.log('success:', results));
A

error: error, success: [1, 2]

B

error: error, success: [1, 2, error]

C

success: [1, 2], error: error

D

error: error, 没有其他输出

← 上一个试卷 JS异步编程入门专题测试
下一个试卷 → JS引擎与运行时原理专题测试

📝 发现内容有误?点击此处直接编辑

想参加完整模拟考试?
小程序提供计时考试、自动评分和详细解析

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库