gpt4 book ai didi

javascript - 我们如何使用生成器以同步方式编写异步代码?

转载 作者:行者123 更新时间:2023-12-02 17:46:54 25 4
gpt4 key购买 nike

我读到 ECMAScript 6 附带的生成器并且已经在 Node.js 开发版本中提供,将使以同步方式编写异步代码变得更加容易。但对我来说真的很难理解,我们如何使用生成器来编写异步代码?

最佳答案

我们首先要记住,使用 ES 生成器,我们可以将一个值传递给 next() 方法,该值将是生成器中yield 语句的返回值。

这个想法是为生成器提供一种 Controller 功能。

在生成器中,每次调用异步函数时,我们都会yield,因此我们将控制权交还给 Controller 函数。 Controller 函数除了在异步操作完成时调用 next() 之外什么都不做。在此期间,我们可以处理其他事件,因此它是非阻塞的。

没有生成器的示例:

// chain of callbacks
function findAuthorOfArticleOfComment (commentID, callback) {
database.comments.find( {id: commentID}
, function (err, comment) {
if (err) return callback(err);
database.articles.find( { id: comment.articleID }
, function (err, article) {
if (err) return callback(err);
database.users.find( { id: article.authorID }
, function (err, author) {
if (err) return callback(err);
callback(author);
});
});
});
}
findAuthorOfArticleOfComment (commentID, function(err, author) {
if(!err) console.log(author);
}

生成器示例:

我们必须使用一个可以控制流程的库,例如 suspendbluebird如果你想将它与 Promise 一起使用。为了更好地理解,我将给出一个不带库的示例。

function* myGenerator(resume, commentID, callback) {
var comment, article, author;
comment = yield database.comments.find( {id: commentID}, resume);
article = yield database.articles.find( {id: comment.articleID}, resume);
author = yield database.users.find( {id: article.authorID}, resume);
};

// in real life we use a library for this !
var findAuthorOfArticleOfComment = function(commentID, callback) {
var resume, theGenerator;
resume = function (err, result) {
var next;
if(err) return callback(err);
next = theGenerator.next(result);
if (next.done) callback(null, result);
}
theGenerator = myGenerator(resume, commentID, callback);
theGenerator.next();
}

// still the same function as first example !
findAuthorOfArticleOfComment (commentID, function(err, author) {
if(!err) console.log(author);
}

我们做什么:

  • 创建生成器,给出一个恢复函数作为第一个参数,参数由函数调用者给出
  • 第一次调用next()。我们的第一个异步函数已达到并且生成器产生。
  • 每次调用 resume 函数时,我们都会获取该值并将其传递给下一个,因此生成器中的代码会继续执行,并且yield 语句会返回正确的值。

在现实生活中,我们将使用一个库,并将生成器作为通用 Controller 函数的参数。因此,我们只需编写生成器,以及 value = yield asyncFunction(parameters,resumeCallback);,或者 value = yield functionReturningPromise(parameters);(如果您使用 Promises) (使用 Promise 兼容库)。这确实是一种以同步方式编写异步代码的好方法。

<小时/>

优秀资源:
http://tobyho.com/2013/06/16/what-are-generators/
http://jlongster.com/A-Closer-Look-at-Generators-Without-Promises

关于javascript - 我们如何使用生成器以同步方式编写异步代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21663839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com