[英]How to write asynchronous functions for Node.js
您似乎將異步IO與異步函數混淆。 node.js使用異步非阻塞IO,因為非阻塞IO更好。 理解它的最好方法是觀看ryan dahl的一些視頻。
如何為Node編寫異步函數?
只寫正常函數,唯一的區別是它們不是立即執行而是作為回調傳遞。
我該如何正確實現錯誤事件處理
通常API會給你一個帶有錯誤作為第一個參數的回調。 例如
database.query('something', function(err, result) {
if (err) handle(err);
doSomething(result);
});
是一種常見的模式。
另一種常見模式是on('error')
。 例如
process.on('uncaughtException', function (err) {
console.log('Caught exception: ' + err);
});
編輯:
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
調用上面的函數
async_function(42, function(val) {
console.log(val)
});
console.log(43);
將異步打印42
到控制台。 特別是process.nextTick
在當前eventloop callstack為空后觸發。 async_function
和console.log(43)
運行后,該調用堆棧為空。 所以我們打印43,然后是42。
您應該對事件循環進行一些閱讀。
僅通過回調是不夠的。 例如,您必須使用settimer來使函數異步。
示例:不是異步函數:
function a() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
b();
};
function b() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
c();
};
function c() {
for(i=0; i<10000000; i++) {
};
console.log("async finished!");
};
a();
console.log("This should be good");
如果你將運行上面的例子,這應該是好的,將不得不等待,直到這些功能將完成工作。
偽多線程(異步)函數:
function a() {
setTimeout ( function() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
b();
}, 0);
};
function b() {
setTimeout ( function() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
c();
}, 0);
};
function c() {
setTimeout ( function() {
for(i=0; i<10000000; i++) {
};
console.log("async finished!");
}, 0);
};
a();
console.log("This should be good");
這個將是異常的異步。 這應該是好的將在異步完成之前寫入。
你應該看一下: Node Tuts第19集 - 異步迭代模式
它應該回答你的問題。
試試這個,它適用於節點和瀏覽器。
isNode = (typeof exports !== 'undefined') &&
(typeof module !== 'undefined') &&
(typeof module.exports !== 'undefined') &&
(typeof navigator === 'undefined' || typeof navigator.appName === 'undefined') ? true : false,
asyncIt = (isNode ? function (func) {
process.nextTick(function () {
func();
});
} : function (func) {
setTimeout(func, 5);
});
如果您知道函數返回一個promise,我建議在JavaScript中使用新的async / await功能。 它使語法看起來是同步的,但是異步工作。 將async
關鍵字添加到函數時,它允許您在該范圍內await
promise:
async function ace() {
var r = await new Promise((resolve, reject) => {
resolve(true)
});
console.log(r); // true
}
如果函數沒有返回一個promise,我建議將它包裝在你定義的新promise中,然后解析你想要的數據:
function ajax_call(url, method) {
return new Promise((resolve, reject) => {
fetch(url, { method })
.then(resp => resp.json())
.then(json => { resolve(json); })
});
}
async function your_function() {
var json = await ajax_call('www.api-example.com/some_data', 'GET');
console.log(json); // { status: 200, data: ... }
}
底線:利用Promises的力量。
我為node.js處理這樣的任務花了太多時間。 我主要是前端人物。
我發現這非常重要,因為所有節點方法異步處理回調,並將其轉換為Promise更好地處理它。
我只想展示一個可能的結果,更精益和可讀。 使用ECMA-6和異步你可以像這樣寫。
async function getNameFiles (dirname) {
return new Promise((resolve, reject) => {
fs.readdir(dirname, (err, filenames) => {
err !== (undefined || null) ? reject(err) : resolve(filenames)
})
})
}
(undefined || null)
用於repl (讀取事件打印循環)場景,使用undefined也可以工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.