推迟和延迟的区别_推迟所有事情

推迟和延迟的区别

James Socol is my manager at Mozilla, and he's an epic boss. Usually your manager is someone who struggles to understand the gist of a webapp's code; hell man, James Socol wrote the code. James has been an awesome help in my Python development, but here he steps into the JavaScript world and talks Deferreds.

James Socol是我在Mozilla的经理,他是一位史诗般的老板。 通常,您的经理是一个难以理解Webapp代码要旨的人; 地狱人,詹姆斯·索科尔( James Socol) 编写了代码。 James在我的Python开发中一直提供了很棒的帮助,但是在这里,他进入了JavaScript世界并谈论了Deferreds。

JavaScript was one of the first languages I ever learned, but as I drifted more toward Python development, I got increasingly out-of-touch with the best ways of doing things.

JavaScript是我所学的第一门语言,但是随着我对Python开发的投入越来越多,我越来越无法与最好的做事方式保持联系。

Then a friend asked me to help on a project. The server was in Node.js and the datastore was MongoDB. Async, webscale, buzzwords, we had it all!

然后一个朋友要我帮助一个项目。 服务器位于Node.js中 ,数据存储区为MongoDB 。 异步,网络规模,流行语,我们拥有了一切!

回调地狱 (Callback Hell)

One of the downsides of everything being asynchronous is that it's very easy to fall into the trap of writing everything as an anonymous callback. You can generally tell this happened by looking at the end of the file.

异步的所有缺点之一是,很容易陷入将所有内容作为匿名回调编写的陷阱。 您通常可以通过查看文件末尾来判断发生这种情况。


                            });
                        });
                    });
                // OH GOD WHY
                });
            });
        });
    // CLOSE EVERYTHING
    });
});


This just hurts me. It's from the end of a view that got objects from two collections. As a Python developer, I can do the same thing in four lines of code!

这让我很受伤。 它是从视图的末尾从两个集合中获取对象的。 作为Python开发人员,我可以用四行代码来做同样的事情!


def home(request):
    foos = Foo.objects.all().orderby('-created')[0:5]
    bars = Bar.objects.all().orderby('-created')[0:5]
    return render(request, 'home.html', {'foos': foos, 'bars': bars})


No, it's not asynchronous (well...), but I think I'd rather spend the CPU cycles and save my brain.

不,它不是异步的( 很好... ),但是我想我宁愿花费CPU周期并节省我的大脑。

I actually delayed coming back to JavaScript because so much of it looks like this.

实际上,我推迟了返回JavaScript的时间,因为很多事情都是这样的。

为什么? (Why?)

Why do I hate this so much?

为什么我讨厌这么多?

When callbacks are nested like this, they usually rely on lexical closure for access to variables, e.g.:

像这样嵌套回调时,它们通常依赖词法闭包来访问变量,例如:


app.get('/', function(req, res) {
    // Open the connection.
    db.open(function(err, db) {
        // Get one collection.
        db.collection('users', function(err, usersColl) {
            // Search the first collection.
            usersColl.find({}, {'limit': 3}, function(err, usersCursor) {
                // Convert the result into an array.
                usersCursor.toArray(function(err, users) {
                    // Get the second collection.
                    db.collection('articles', function(err, artColl) {
                        // Search the second collection.
                        artColl.find({}, {'limit': 3}, function(err, artCursor) {
                            // Convert the result into an array.
                            artCursor.toArray(function(err, articles) {
                                // Now we have two arrays, users and articles, in scope.
                                // Render the home page.
                                res.render('home.ejs', {'users': users, 'articles': articles});


The innermost function only has access to the array users because it's closed over several other functions.

最内层的功能仅对数组users具有访问权限,因为它已关闭了其他多个功能。

There are at least 3 things wrong with this:

至少有3件事是错误的:

  1. Both queries are asynchronous, but we do them in serial instead of parallel. That's a waste of time and burns most of our "async" advantages right off the bat.

    这两个查询都是异步的,但我们以串行而不是并行的方式进行。 那是浪费时间,马上烧掉了我们大多数“异步”优势。
  2. Because these inner functions depend on lexical closure, they're impossible to test in smaller fragments and difficult to refactor to become more testable.

    由于这些内部函数取决于词法闭包,因此无法在较小的片段中进行测试,并且难以重构以变得更易于测试。
  3. Rendering a template in the middle of a database query is no better than a database query in the middle of a template:

    在数据库查询中间呈现模板并不比在模板中间呈现数据库查询更好:

<h1><?= mysql_query($my, "SELECT title FROM posts WHERE..."); ?></h1>


And finally, #4, OH GOD THE NESTING.

最后,#4,哦,嵌套

但是之后! (But then!)

Months later, at a hack day, researching something completely different, I stumbled across jQuery.Deferred() and it was like I had come out of the cave and seen the light.

几个月后,在黑客日,研究了完全不同的东西,我偶然发现了jQuery.Deferred() ,就好像我从山洞里出来了一样。

I had seen projects like tame.js, which I like in principle, but I find overly complicated in practice. I thought those were the options: callback hell or precompilers that spit out mounds of impenetrable code.

我看过像tame.js这样的项目,我原则上喜欢,但是在实践中我发现过于复杂。 我认为这些是选项:回调地狱或吐出难以理解的代码的预编译器。

All of a sudden my functions could be functions again! They could take arguments instead of relying on scope. They could be run in parallel. They could be nice and flat!

突然我的功能可能又变成了功能! 他们可以争论而不是依赖范围。 它们可以并行运行。 他们可能很好,很平坦!


var mongodb = require('mongodb');
var express = require('express');
var Deferred = require('Deferred');

var app = express.createServer();
var db = new mongodb.Db('mysite',
                        new mongodb.Server('localhost', 27027, {}),
                        {native_parser: true});

var Deferred = require('Deferred');

// Only do this once. Keep it somewhere else.
function getArray(db, coll, search, options) {
    var def = Deferred();
    db.open(function(err, db) {
        if (err) def.reject(err);
        db.collection(coll, function(err, collection) {
            if (err) def.reject(err);
            collection.find(search, options, function(err, cursor) {
                if (err) def.reject(err);
                cursor.toArray(function(err, arr) {
                    if (err) def.reject(err);
                    def.resolve(arr);
                });
            });
        });
    });
    return def.promise();
}

function home(req, res) {
    var uDef = getArray(db, 'users', {}, {'limit': 3});
    var aDef = getArray(db, 'articles', {}, {'limit': 4});
    var lookup = Deferred.when(uDef, aDef);
    lookup.done(function(users, articles)) {
        res.render('home.ejs', {'users': users, 'articles': articles});
    }).fail(function(err) {
        res.render('error.ejs', {'error': err})
    });
}

app.get('/', home);


啊,那更好 (Ah, That's Better)

A lot of library code, like Dojo and jQuery, takes advantage of Promises and Deferreds to make things cleaner. I hope that more and more userland code will do the same.

许多库代码,例如DojojQuery ,都利用Promises和Deferreds使内容更整洁。 我希望越来越多的userland代码也能做到这一点。

Finding Deferreds helped me learn to love JavaScript again. It's such a fun, flexible, interesting language, so I'm glad complex code can be easy to test and fun to read.

查找Deferreds帮助我再次学习了JavaScript。 这是一种有趣,灵活,有趣的语言,所以我很高兴复杂的代码易于测试且易于阅读。

翻译自: https://davidwalsh.name/deferred

推迟和延迟的区别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值