Javascript 如何为 Node.js 编写异步函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6898779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 23:40:09  来源:igfitidea点击:

How to write asynchronous functions for Node.js

javascriptasynchronousnode.js

提问by Kriem

I've tried to research on how exactly asynchronous functions should be written. After a lot of plowing through a lot of documentation, it's still unclear to me.

我试图研究应该如何编写异步函数。在翻阅了大量文档之后,我仍然不清楚。

How do I write asynchronous functions for Node? How should I implement error event handling correctly?

如何为 Node 编写异步函数?我应该如何正确实现错误事件处理?

Another way to ask my question would be this: How should I interpret the following function?

问我的问题的另一种方法是:我应该如何解释以下函数?

var async_function = function(val, callback){
    process.nextTick(function(){
        callback(val);
    });
};

Also, I found this question on SO("How do I create a non-blocking asynchronous function in node.js?") interesting. I don't feel like it has been answered yet.

另外,我在 SO(“如何在 node.js 中创建非阻塞异步函数?”)发现这个问题很有趣。我觉得还没有人回答。

采纳答案by Raynos

You seem to be confusing asynchronous IO with asynchronous functions. node.js uses asynchronous non-blocking IO because non blocking IO is better. The best way to understand it is to go watch some videos by ryan dahl.

您似乎将异步 IO 与异步函数混淆了。node.js 使用异步非阻塞 IO,因为非阻塞 IO 更好。理解它的最好方法是观看 ryan dahl 的一些视频。

How do I write asynchronous functions for Node?

如何为 Node 编写异步函数?

Just write normal functions, the only difference is that they are not executed immediately but passed around as callbacks.

只需编写普通函数,唯一的区别是它们不会立即执行,而是作为回调传递。

How should I implement error event handling correctly

我应该如何正确实现错误事件处理

Generally API's give you a callback with an err as the first argument. For example

通常,API 会给您一个回调,并将 err 作为第一个参数。例如

database.query('something', function(err, result) {
  if (err) handle(err);
  doSomething(result);
});

Is a common pattern.

是一种常见的模式。

Another common pattern is on('error'). For example

另一种常见的模式是on('error'). 例如

process.on('uncaughtException', function (err) {
  console.log('Caught exception: ' + err);
});

Edit:

编辑:

var async_function = function(val, callback){
    process.nextTick(function(){
        callback(val);
    });
};

The above function when called as

上述函数调用时

async_function(42, function(val) {
  console.log(val)
});
console.log(43);

Will print 42to the console asynchronously. In particular process.nextTickfires after the current eventloop callstack is empty. That call stack is empty after async_functionand console.log(43)have run. So we print 43 followed by 42.

42异步打印到控制台。特别是process.nextTick在当前事件循环调用堆栈为空后触发。这调用堆栈是空后async_functionconsole.log(43)已经运行。所以我们打印 43 然后是 42。

You should probably do some reading on the event loop.

您可能应该对事件循环进行一些阅读。

回答by calmbird

Just passing by callbacks is not enough. You have to use settimer for example, to make function async.

仅仅通过回调是不够的。例如,您必须使用 settimer 来使函数异步。

Examples: Not async functions:

示例: 非异步函数:

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");

If you will run above example, This should be good, will have to wait untill those functions will finish to work.

如果您将运行上面的示例,这应该很好,必须等到这些功能完成才能工作。

Pseudo multithread (async) functions:

伪多线程(异步)函数:

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");

This one will be trully async. This should be good will be writen before async finished.

这将是真正的异步。这应该会在异步完成之前写好。

回答by Cris-O

You should watch this: Node Tuts episode 19 - Asynchronous Iteration Patterns

你应该看这个:Node Tuts 第 19 集 - 异步迭代模式

It should answers your questions.

它应该回答你的问题。

回答by ryanwaite28

If you KNOW that a function returns a promise, i suggest using the new async/await features in JavaScript. It makes the syntax look synchronous but work asynchronously. When you add the asynckeyword to a function, it allows you to awaitpromises in that scope:

如果你知道一个函数会返回一个 promise,我建议你使用 JavaScript 中新的 async/await 特性。它使语法看起来同步但异步工作。当您将async关键字添加到函数时,它允许您await在该范围内承诺:

async function ace() {
  var r = await new Promise((resolve, reject) => {
    resolve(true)
  });

  console.log(r); // true
}

if a function does not return a promise, i recommend wrapping it in a new promise that you define, then resolve the data that you want:

如果函数不返回承诺,我建议将其包装在您定义的新承诺中,然后解析您想要的数据:

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: ... }
}

Bottom line: leverage the power of Promises.

底线:利用 Promise 的力量。

回答by Pradeep

Try this, it works for both node and the browser.

试试这个,它适用于节点和浏览器。

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);
});

回答by Yoarthur

I've dealing too many hours for such task in for node.js. I'm mainly front-end guy.

我在 node.js 中为这样的任务处理了太多时间。我主要是前端人员。

I find this quite important, because all node methods asyncronous deal with callback, and transform it into Promise is better to handle it.

我觉得这很重要,因为所有节点方法异步处理回调,将其转换为 Promise 更好地处理它。

I Just want to show a possible outcome, more lean and readable. Using ECMA-6 with async you can write it like this.

我只是想展示一个可能的结果,更精简和可读。将 ECMA-6 与异步一起使用,您可以像这样编写它。

 async function getNameFiles (dirname) {
  return new Promise((resolve, reject) => {
    fs.readdir(dirname, (err, filenames) => {
      err !== (undefined || null) ? reject(err) : resolve(filenames)
    })
  })
}

the (undefined || null)is for repl(read event print loop) scenarios, using undefined also work.

(undefined || null)是用于repl(读取事件打印循环)场景,使用 undefined 也可以工作。