ví dụ đơn giản về callbacks nodeJs


120

bất kỳ ai có thể cho tôi một ví dụ đơn giản về callback nodeJs, tôi đã tìm kiếm giống nhau trên nhiều trang web nhưng không thể hiểu nó đúng, Vui lòng cho tôi một ví dụ đơn giản.

getDbFiles(store, function(files){
    getCdnFiles(store, function(files){
    })
})

Tôi muốn làm một cái gì đó như thế ...


một ví dụ về cách viết một hàm nhận một cuộc gọi lại làm đối số?
Gntem

yeah một cái gì đó như vậy, bất kỳ ví dụ đơn giản nào giúp tôi hiểu nó.
Bhushan Goel

2
Gọi lại là một hàm mà bạn truyền dưới dạng tham số cho một hàm khác ... Làm ơn Google -> "javascript gọi lại" -> kết quả đầu tiên
Gabriel Llamas

Câu trả lời:


198
var myCallback = function(data) {
  console.log('got data: '+data);
};

var usingItNow = function(callback) {
  callback('get it?');
};

Bây giờ hãy mở nút hoặc bảng điều khiển trình duyệt và dán các định nghĩa trên.

Cuối cùng sử dụng nó với dòng tiếp theo:

usingItNow(myCallback);

Tuân theo các quy ước về lỗi kiểu nút

Costa hỏi điều này sẽ trông như thế nào nếu chúng ta tuân theo các quy ước gọi lại lỗi nút.

Trong quy ước này, lệnh gọi lại sẽ nhận được ít nhất một đối số, đối số đầu tiên, là một lỗi. Theo tùy chọn, chúng tôi sẽ có một hoặc nhiều đối số bổ sung, tùy thuộc vào ngữ cảnh. Trong trường hợp này, ngữ cảnh là ví dụ ở trên của chúng tôi.

Ở đây tôi viết lại ví dụ của chúng tôi trong quy ước này.

var myCallback = function(err, data) {
  if (err) throw err; // Check for the error and throw if it exists.
  console.log('got data: '+data); // Otherwise proceed as usual.
};

var usingItNow = function(callback) {
  callback(null, 'get it?'); // I dont want to throw an error, so I pass null for the error argument
};

Nếu chúng ta muốn mô phỏng một trường hợp lỗi, chúng ta có thể xác định bằng cách sử dụngItNow như thế này

var usingItNow = function(callback) {
  var myError = new Error('My custom error!');
  callback(myError, 'get it?'); // I send my error as the first argument.
};

Cách sử dụng cuối cùng hoàn toàn giống như ở trên:

usingItNow(myCallback);

Sự khác biệt duy nhất về hành vi sẽ phụ thuộc vào phiên bản usingItNowbạn đã xác định: phiên bản cung cấp "giá trị trung thực" (đối tượng Lỗi) cho lệnh gọi lại cho đối số đầu tiên hoặc phiên bản cung cấp giá trị rỗng cho đối số lỗi .


Vậy điều này trông như thế nào với lỗi là quy ước tham số đầu tiên?
Costa

113

Một hàm gọi lại chỉ đơn giản là một hàm mà bạn truyền vào một hàm khác để hàm đó có thể gọi nó sau này. Điều này thường thấy trong các API không đồng bộ ; lệnh gọi API trả về ngay lập tức bởi vì nó không đồng bộ, vì vậy bạn chuyển một hàm vào nó mà API có thể gọi khi nó thực hiện xong tác vụ không đồng bộ của nó.

Ví dụ đơn giản nhất mà tôi có thể nghĩ đến trong JavaScript là setTimeout()hàm. Đó là một hàm toàn cục chấp nhận hai đối số. Đối số đầu tiên là hàm gọi lại và đối số thứ hai là độ trễ tính bằng mili giây. Hàm được thiết kế để đợi một khoảng thời gian thích hợp, sau đó gọi hàm gọi lại của bạn.

setTimeout(function () {
  console.log("10 seconds later...");
}, 10000);

Bạn có thể đã thấy đoạn mã trên trước đây nhưng không nhận ra rằng hàm bạn đang chuyển vào được gọi là hàm gọi lại. Chúng tôi có thể viết lại đoạn mã trên để làm cho nó rõ ràng hơn.

var callback = function () {
  console.log("10 seconds later...");
};
setTimeout(callback, 10000);

Các lệnh gọi lại được sử dụng khắp nơi trong Node vì Node được xây dựng từ đầu để không đồng bộ trong mọi thứ mà nó thực hiện. Ngay cả khi nói chuyện với hệ thống tệp. Đó là lý do tại sao rất nhiều Node API nội bộ chấp nhận các hàm gọi lại làm đối số thay vì trả về dữ liệu mà bạn có thể gán cho một biến. Thay vào đó, nó sẽ gọi hàm gọi lại của bạn, truyền dữ liệu bạn muốn làm đối số. Ví dụ: bạn có thể sử dụng fsthư viện của Node để đọc một tệp. Các fsmô-đun lộ hai hàm API duy nhất: readFilereadFileSync.

Các readFilechức năng là không đồng bộ trong khi readFileSyncrõ ràng là không. Bạn có thể thấy rằng họ dự định bạn sử dụng các cuộc gọi không đồng bộ bất cứ khi nào có thể vì họ đã gọi chúng readFilereadFileSyncthay vì readFilereadFileAsync. Đây là một ví dụ về việc sử dụng cả hai hàm.

Đồng bộ:

var data = fs.readFileSync('test.txt');
console.log(data);

Đoạn mã trên chặn thực thi luồng cho đến khi tất cả nội dung của test.txtđược đọc vào bộ nhớ và được lưu trữ trong biến data. Trong nút, điều này thường được coi là thực hành xấu. Có những lúc nó hữu ích, chẳng hạn như khi viết một đoạn script nhỏ nhanh chóng để làm một việc đơn giản nhưng tẻ nhạt và bạn không quan tâm lắm đến việc tiết kiệm từng nano giây mà bạn có thể.

Không đồng bộ (có gọi lại):

var callback = function (err, data) {
  if (err) return console.error(err);
  console.log(data);
};
fs.readFile('test.txt', callback);

Đầu tiên chúng ta tạo một hàm gọi lại chấp nhận hai đối số errdata. Một vấn đề với các hàm không đồng bộ là việc bẫy lỗi trở nên khó khăn hơn nên rất nhiều API kiểu gọi lại chuyển lỗi làm đối số đầu tiên cho hàm gọi lại. Cách tốt nhất là kiểm tra xem errcó giá trị hay không trước khi bạn làm bất cứ điều gì khác. Nếu vậy, hãy dừng thực hiện lệnh gọi lại và ghi lại lỗi.

Các cuộc gọi đồng bộ có lợi thế hơn khi có các ngoại lệ được ném ra vì bạn có thể đơn giản bắt chúng bằng một try/catchkhối.

try {
  var data = fs.readFileSync('test.txt');
  console.log(data);
} catch (err) {
  console.error(err);
}

Trong các hàm không đồng bộ, nó không hoạt động theo cách đó. Lệnh gọi API trả về ngay lập tức nên không có gì để bắt với try/catch. Các API không đồng bộ thích hợp sử dụng lệnh gọi lại sẽ luôn bắt lỗi riêng của chúng và sau đó chuyển các lỗi đó vào lệnh gọi lại nơi bạn có thể xử lý khi thấy phù hợp.

Ngoài các lệnh gọi lại, có một kiểu API phổ biến khác thường được sử dụng gọi là lời hứa. Nếu bạn muốn đọc về chúng thì bạn có thể đọc toàn bộ bài đăng trên blog mà tôi đã viết dựa trên câu trả lời này tại đây .


3
một cách chuyển tải khái niệm khá phức tạp nhưng ngắn gọn; cho một người mới bắt đầu node.js như tôi ...
kmonsoor

3
+1 để cung cấp nhiều ngữ cảnh. Không chỉ các hàm gọi lại trông như thế nào mà còn cả chúng là gì, tại sao chúng được sử dụng và tại sao chúng được sử dụng nhiều. Thực sự hữu ích cho người mới bắt đầu.
Azurespot

1
Tuyệt quá! đây có thể là một bài đăng của chính nó!
Pablo Glez

1
Đó là , và nó bao gồm phần thứ hai về những lời hứa;)
Chev

1
Đây là một lời giải thích tốt hơn nhiều so với câu trả lời được chấp nhận! Tôi muốn mọi câu trả lời được chấp nhận ở đây trên VẬY phải như vậy - không chỉ là một đoạn mã giải quyết vấn đề, mà còn là TẠI SAOCÁCH nó giải quyết vấn đề. Về cơ bản, câu trả lời và callbackhell này sẽ cung cấp cho bạn một hiểu biết khá chắc chắn về callback là gì.
RusI

10

Đây là một ví dụ về sao chép tệp văn bản với fs.readFilefs.writeFile:

var fs = require('fs');

var copyFile = function(source, destination, next) {
  // we should read source file first
  fs.readFile(source, function(err, data) {
    if (err) return next(err); // error occurred
    // now we can write data to destination file
    fs.writeFile(destination, data, next);
  });
};

Và đó là một ví dụ về việc sử dụng copyFilehàm:

copyFile('foo.txt', 'bar.txt', function(err) {
  if (err) {
    // either fs.readFile or fs.writeFile returned an error
    console.log(err.stack || err);
  } else {
    console.log('Success!');
  }
});

Mẫu node.js chung cho thấy rằng đối số đầu tiên của hàm gọi lại là một lỗi. Bạn nên sử dụng mẫu này vì tất cả các mô-đun luồng điều khiển đều dựa vào nó:

next(new Error('I cannot do it!')); // error

next(null, results); // no error occurred, return result

2
tiếp theo là gì? Kết quả biến là gì = cái gì đang được gọi là gì?
Các Nomadic Coder

3
@SemicolonWarrier một con trỏ cho tôi cũng như những người khác: stackoverflow.com/questions/5384526/javascript-node-js-next
kmonsoor

7

Hãy thử ví dụ này đơn giản nhất bạn có thể đọc, chỉ cần sao chép lưu newfile.js do node newfile để chạy ứng dụng.

function myNew(next){
    console.log("Im the one who initates callback");
    next("nope", "success");
}


myNew(function(err, res){
    console.log("I got back from callback",err, res);
});

3

chúng tôi đang tạo một chức năng đơn giản như

callBackFunction (data, function ( err, response ){
     console.log(response)
}) 

// callbackfunction 
function callBackFuntion (data, callback){
    //write your logic and return your result as
callback("",result) //if not error
callback(error, "") //if error
}

1
const fs = require('fs');

fs.stat('input.txt', function (err, stats) {
    if(err){
        console.log(err);
    } else {
        console.log(stats);
        console.log('Completed Reading File');
    }
});

'fs' là một mô-đun nút giúp bạn đọc tệp. Hàm gọi lại sẽ đảm bảo rằng tệp có tên 'input.txt' của bạn được đọc hoàn toàn trước khi nó được thực thi. Hàm fs.stat () là để lấy thông tin về tệp như kích thước tệp, ngày tạo và ngày sửa đổi.


1

//delay callback function
function delay (seconds, callback){
    setTimeout(() =>{
      console.log('The long delay ended');
      callback('Task Complete');
    }, seconds*1000);
}
//Execute delay function
delay(1, res => {  
    console.log(res);  
})


0

A callbacklà một hàm được truyền dưới dạng tham số cho a Higher Order Function( wikipedia ). Một cách triển khai đơn giản của một cuộc gọi lại sẽ là:

const func = callback => callback('Hello World!');

Để gọi hàm, chỉ cần chuyển một hàm khác làm đối số cho hàm được xác định.

func(string => console.log(string));

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.