aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
SAVED POSTS
aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
aedev.net
No Result
View All Result
Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Return trong finally có thể che cả return lẫn lỗi ban đầu

Suong Nguyen by Suong Nguyen
01/11/2026
in Phỏng vấn
0
585
SHARES
3.2k
VIEWS
Summarize with ChatGPTShare to Facebook

Một hàm gặp lỗi nhưng caller lại nhận chuỗi “đã dọn xong”. Hãy kiểm tra xem khối finally có đang return hay không. Câu lệnh tưởng chỉ phục vụ cleanup có thể thay thế kết quả hoặc exception mà hàm đang chuẩn bị trả ra ngoài.

Các snippet trong bài đã chạy bằng Node.js 24.18.1, đối chiếu MDN ngày 01/11/2026. Ví dụ tạo giá trị và lỗi trong RAM, không mở file hoặc gọi dịch vụ. Mục tiêu là hiểu luồng điều khiển trước khi áp dụng vào logic tài nguyên thật.

1. Return từ try chưa kết thúc toàn bộ construct

Khi đi qua try/finally, return của try phải chờ finally hoàn tất. Nếu finally đưa ra return khác, quyết định mới thay thế quyết định trước đó. Điều này không phải ghép hai kết quả lại với nhau.

import assert from 'node:assert/strict';

function replacedValue() {
  try {
    return 'kết quả chính';
  } finally {
    return 'kết quả cleanup';
  }
}

assert.equal(replacedValue(), 'kết quả cleanup');
console.log(replacedValue());

Trong fixture, caller nhận kết quả cleanup. Đừng biến mẫu này thành cách “chuẩn hóa” mọi kết quả sau cùng: nó làm người đọc khó thấy giá trị thật được chọn ở nhánh nào.

2. Một throw cũng có thể bị che

Không cần có catch để finally thay đổi luồng. Một lỗi đang chuẩn bị truyền ra ngoài có thể bị return trong finally thay thế.

import assert from 'node:assert/strict';

const original = new Error('lỗi chính');
function maskedError() {
  try {
    throw original;
  } finally {
    return 'đã dọn xong';
  }
}

assert.equal(maskedError(), 'đã dọn xong');
assert.doesNotThrow(() => maskedError());

Caller không nhận original qua hàm này. Nếu log cleanup khiến bạn tưởng lỗi đã được xử lý đúng, hãy kiểm tra cả giá trị mà caller nhận và nhánh reject/throw, thay vì chỉ kiểm tra một dòng log có được in không.

3. Cleanup không cần return để giữ kết quả

Mẫu đồng bộ dưới đây để task quyết định kết quả, còn cleanup ghi một dấu hiệu local. Hai đường đi thành công và thất bại đều được kiểm tra.

import assert from 'node:assert/strict';

function runWithCleanup(task, cleanup) {
  try {
    return task();
  } finally {
    cleanup();
  }
}

const trace = [];
assert.equal(runWithCleanup(() => 42, () => trace.push('clean')), 42);
const original = new Error('task failed');
assert.throws(
  () => runWithCleanup(() => { throw original; }, () => trace.push('clean')),
  error => error === original,
);
assert.deepEqual(trace, ['clean', 'clean']);

Đây là helper cho task đồng bộ trong fixture. Trả một Promise từ task không tự khiến finally đợi Promise đó hoàn tất; đừng dùng helper này rồi tuyên bố tài nguyên async đã được giữ đến cuối công việc.

Nếu chính cleanup ném lỗi, lỗi đó vẫn có thể thay đổi kết quả đi ra. Khi cleanup thật có thể thất bại, cần chính sách giữ hoặc ghi nhận lỗi chính và lỗi cleanup rõ ràng. Việc bỏ return giải quyết một bẫy cụ thể, không đảm bảo mọi thao tác cleanup đều vô hại.

4. Promise.finally có hợp đồng khác

Callback truyền vào Promise.finally là một hàm riêng. Giá trị return thông thường của callback không thay thế giá trị fulfilled ban đầu; nhưng throw hoặc Promise bị reject từ callback có thể làm chuỗi reject.

import assert from 'node:assert/strict';

assert.equal(await Promise.resolve(42).finally(() => 99), 42);
const original = new Error('primary');
await assert.rejects(
  Promise.reject(original).finally(() => 'ignored'),
  error => error === original,
);
const cleanupError = new Error('cleanup');
await assert.rejects(
  Promise.resolve(42).finally(() => { throw cleanupError; }),
  error => error === cleanupError,
);

Chạy các snippet có import hoặc top-level await dưới dạng file .mjs. Các assertions đã đạt trên Node nêu trên. Không suy ngữ nghĩa của block finally từ việc hai cấu trúc có cùng tên gọi.

Cách giải thích khi phỏng vấn

Theo dõi ba bước: try hoặc catch định đi ra bằng gì, finally thực hiện gì, rồi caller thực sự nhận gì. Thử riêng return, throw và cleanup cũng throw. Một câu trả lời có fixture kiểm tra lỗi giữ nguyên thường rõ hơn câu “finally luôn chạy” đứng riêng lẻ.

Trong code review, ưu tiên cleanup không thay đổi luồng chính nếu không có chủ đích rõ ràng. Những ví dụ này nói về luồng JavaScript trong runtime đang chạy, không cam kết cleanup khi tiến trình bị kết thúc đột ngột.

Nguồn tham khảo

  • MDN: try…catch và return trong finally
  • MDN: return
  • MDN: Promise.finally

Tags: Error handlingJavaScriptPhỏng vấn
SummarizeShare234
Suong Nguyen

Suong Nguyen

Related Stories

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Vì sao Array(3).map không gọi callback ba lần?

by Suong Nguyen
31/10/2026
0

Phân biệt empty slot với undefined, dùng Array.from để tạo phần tử và tránh bẫy fill cùng một object.

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Phỏng vấn JavaScript: await forEach không chờ các callback async

by Suong Nguyen
30/10/2026
0

Dùng một gate Promise điều khiển được để thấy forEach trả về trước callback, rồi viết lại vòng lặp có hợp đồng chờ rõ ràng.

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Phỏng vấn JavaScript: vì sao tách method thành callback lại mất this?

by Suong Nguyen
29/10/2026
0

Theo dõi cách gọi method, callback độc lập, bind và arrow wrapper bằng ví dụ đồng bộ trong strict mode.

Lập trình viên chuẩn bị phỏng vấn fresher React Native với laptop, điện thoại và thẻ câu hỏi

Phỏng vấn JavaScript: vì sao callback trong vòng lặp đều đọc cùng giá trị?

by Suong Nguyen
28/10/2026
0

Tách vấn đề closure khỏi timer bằng các callback gọi sau vòng lặp, rồi so var, let và hàm tạo binding riêng.

0 0 votes
Article Rating
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
AE Dev

AE Dev mang đến các bài viết về lập trình, mobile app, backend, frontend, WordPress và công nghệ, phù hợp cho developer muốn học hỏi và cập nhật kiến thức thực tế.

Recent Posts

  • React Native useColorScheme: đổi theme mà không cache màu từ module
  • Return trong finally có thể che cả return lẫn lỗi ban đầu
  • Android Intent extra: thiếu dữ liệu khác với giá trị 0

Categories

  • AI
  • Backend
  • Đánh giá
  • DevOps
  • Flutter
  • Hướng dẫn
  • Lập trình Mobile
  • Phỏng vấn
  • React Native
  • Uncategorized

Weekly Newsletter

  • Buy JNews
  • Support Forum
  • Pre-sale Question
  • Contact Us

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • AI
  • Mobile
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
  • Flutter

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

wpDiscuz
0
0
Would love your thoughts, please comment.x
()
x
| Reply