函数 then() 在 JavaScript 中是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3884281/
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 06:29:56  来源:igfitidea点击:

What does the function then() mean in JavaScript?

javascript

提问by Kay Pale

I've been seeing code that looks like:

我一直在看到这样的代码:

myObj.doSome("task").then(function(env) {
    // logic
});

Where does then()come from?

哪里then()来的呢?

回答by Sid

The traditional way to deal with asynchronous calls in JavaScript has been with callbacks. Say we had to make three calls to the server, one after the other, to set up our application. With callbacks, the code might look something like the following (assuming a xhrGET function to make the server call):

在 JavaScript 中处理异步调用的传统方法是使用回调。假设我们必须对服务器进行三个调用,一个接一个,以设置我们的应用程序。对于回调,代码可能如下所示(假设使用 xhrGET 函数进行服务器调用):

// Fetch some server configuration
    xhrGET('/api/server-config', function(config) {
        // Fetch the user information, if he's logged in
        xhrGET('/api/' + config.USER_END_POINT, function(user) {
            // Fetch the items for the user
            xhrGET('/api/' + user.id + '/items', function(items) {
                // Actually display the items here
            });
        });
    });

In this example, we first fetch the server configuration. Then based on that, we fetch information about the current user, and then finally get the list of items for the current user. Each xhrGET call takes a callback function that is executed when the server responds.

在这个例子中,我们首先获取服务器配置。然后基于此,我们获取有关当前用户的信息,然后最终获取当前用户的项目列表。每个 xhrGET 调用都采用一个回调函数,该函数在服务器响应时执行。

Now of course the more levels of nesting we have, the harder the code is to read, debug, maintain, upgrade, and basically work with. This is generally known as callback hell. Also, if we needed to handle errors, we need to possibly pass in another function to each xhrGET call to tell it what it needs to do in case of an error. If we wanted to have just one common error handler, that is not possible.

现在当然,我们拥有的嵌套级别越多,代码就越难阅读、调试、维护、升级和基本工作。这通常被称为回调地狱。此外,如果我们需要处理错误,我们可能需要将另一个函数传递给每个 xhrGET 调用,以告诉它在发生错误时需要做什么。如果我们只想拥有一个常见的错误处理程序,那是不可能的。

The Promise API was designed to solve this nesting problem and the problem of error handling.

Promise API 就是为了解决这个嵌套问题和错误处理问题而设计的。

The Promise API proposes the following:

Promise API 提出以下建议:

  1. Each asynchronous task will return a promiseobject.
  2. Each promiseobject will have a thenfunction that can take two arguments, a successhandler and an errorhandler.
  3. The success orthe error handler in the thenfunction will be called only once, after the asynchronous task finishes.
  4. The thenfunction will also return a promise, to allow chaining multiple calls.
  5. Each handler (success or error) can return a value, which will be passed to the next function as an argument, in the chain of promises.
  6. If a handler returns a promise(makes another asynchronous request), then the next handler (success or error) will be called only after that request is finished.
  1. 每个异步任务都会返回一个promise对象。
  2. 每个promise对象都有一个then可以接受两个参数的success函数,一个error处理程序和一个处理程序。
  3. 在异步任务完成后,函数中的成功错误处理程序then将只调用一次
  4. then函数还将返回一个promise, 以允许链接多个调用。
  5. 每个处理程序(成功或错误)都可以返回 a value,它将作为sargument链中promise的an 传递给下一个函数。
  6. 如果处理程序返回 a promise(发出另一个异步请求),则仅在该请求完成后才会调用下一个处理程序(成功或错误)。

So the previous example code might translate to something like the following, using promises and the $httpservice(in AngularJs):

因此,使用 promise 和$http服务(在 AngularJs 中),前面的示例代码可能会转换为以下内容:

$http.get('/api/server-config').then(
    function(configResponse) {
        return $http.get('/api/' + configResponse.data.USER_END_POINT);
    }
).then(
    function(userResponse) {
        return $http.get('/api/' + userResponse.data.id + '/items');
    }
).then(
    function(itemResponse) {
        // Display items here
    }, 
    function(error) {
        // Common error handling
    }
);

Propagating Success and Error

传播成功和错误

Chaining promises is a very powerful technique that allows us to accomplish a lot of functionality, like having a service make a server call, do some postprocessing of the data, and then return the processed data to the controller. But when we work with promisechains, there are a few things we need to keep in mind.

链接承诺是一种非常强大的技术,它允许我们完成很多功能,比如让服务调用服务器,对数据进行一些后处理,然后将处理后的数据返回给控制器。但是当我们使用 promise链条时,我们需要记住一些事情。

Consider the following hypothetical promisechain with three promises, P1, P2, and P3. Each promisehas a success handler and an error handler, so S1 and E1 for P1, S2 and E2 for P2, and S3 and E3 for P3:

考虑以下promise具有三个承诺 P1、P2 和 P3 的假设链。每个promise都有一个成功处理程序和一个错误处理程序,所以 S1 和 E1 用于 P1,S2 和 E2 用于 P2,S3 和 E3 用于 P3:

xhrCall()
  .then(S1, E1) //P1
  .then(S2, E2) //P2
  .then(S3, E3) //P3

In the normal flow of things, where there are no errors, the application would flow through S1, S2, and finally, S3. But in real life, things are never that smooth. P1 might encounter an error, or P2 might encounter an error, triggering E1 or E2.

在正常的事物流中,如果没有错误,应用程序将流经 S1、S2,最后是 S3。但在现实生活中,事情从来没有那么顺利。P1 可能遇到错误,或者 P2 可能遇到错误,触发 E1 或 E2。

Consider the following cases:

考虑以下情况:

? We receive a successful response from the server in P1, but the data returned is not correct, or there is no data available on the server (think empty array). In such a case, for the next promise P2, it should trigger the error handler E2.

? 我们在 P1 中收到服务器的成功响应,但是返回的数据不正确,或者服务器上没有可用的数据(想想空数组)。在这种情况下,对于下一个承诺 P2,它应该触发错误处理程序 E2。

? We receive an error for promise P2, triggering E2. But inside the handler, we have data from the cache, ensuring that the application can load as normal. In that case, we might want to ensure that after E2, S3 is called.

? 我们收到承诺 P2 的错误,触发 E2。但是在处理程序内部,我们有来自缓存的数据,确保应用程序可以正常加载。在这种情况下,我们可能希望确保在 E2 之后调用 S3。

So each time we write a success or an error handler, we need to make a call—given our current function, is this promise a success or a failure for the next handler in the promise chain?

因此,每次我们编写成功或错误处理程序时,我们都需要进行调用——给定我们当前的函数,这个承诺对于承诺链中的下一个处理程序是成功还是失败?

If we want to trigger the success handler for the next promise in the chain, we can just return a value from the success or the error handler

如果我们想为链中的下一个承诺触发成功处理程序,我们可以只从成功或错误处理程序返回一个值

If, on the other hand, we want to trigger the error handler for the next promise in the chain, we can do that using a deferredobject and calling its reject()method

另一方面,如果我们想为链中的下一个承诺触发错误处理程序,我们可以使用一个deferred对象并调用它的reject()方法来做到这一点

Now What is deferred object?

Deferred objects in jQuery represents a unit of work that will be completed later, typically asynchronously. Once the unit of work completes, the deferredobject can be set to resolved or failed.

A deferredobject contains a promiseobject. Via the promiseobject you can specify what is to happen when the unit of work completes. You do so by setting callback functions on the promiseobject.

现在什么是延迟对象?

jQuery 中的延迟对象表示稍后将完成的工作单元,通常是异步完成的。工作单元完成后,deferred可以将对象设置为已解决或失败。

一个deferred对象包含一个promise对象。通过promise对象,您可以指定工作单元完成时要发生的事情。您可以通过在promise对象上设置回调函数来实现。

Deferred objects in Jquery : https://api.jquery.com/jquery.deferred/

Jquery 中的延迟对象:https: //api.jquery.com/jquery.deferred/

Deferred objects in AngularJs : https://docs.angularjs.org/api/ng/service/$q

AngularJs 中的延迟对象:https://docs.angularjs.org/api/ng/service/ $q

回答by almoraleslopez

then() function is related to "Javascript promises" that are used in some libraries or frameworks like jQuery or AngularJS.

then() 函数与某些库或框架(如 jQuery 或 AngularJS)中使用的“Javascript 承诺”相关。

A promise is a pattern for handling asynchronous operations. The promise allows you to call a method called "then" that lets you specify the function(s) to use as the callbacks.

承诺是一种处理异步操作的模式。Promise 允许您调用名为“then”的方法,该方法可让您指定用作回调的函数。

For more information see: http://wildermuth.com/2013/8/3/JavaScript_Promises

有关更多信息,请参阅:http: //wildermuth.com/2013/8/3/JavaScript_Promises

And for Angular promises: http://liamkaufman.com/blog/2013/09/09/using-angularjs-promises/

对于 Angular 承诺:http: //liamkaufman.com/blog/2013/09/09/using-angularjs-promises/

回答by user113716

To my knowledge, there isn't a built-in then()method in javascript(at the time of this writing).

据我所知,(在撰写本文时)中没有内置then()方法javascript

It appears that whatever it is that doSome("task")is returning has a method called then.

似乎无论doSome("task")返回的是什么,都有一个名为then.

If you log the return result of doSome()to the console, you should be able to see the properties of what was returned.

如果您将 的返回结果记录doSome()到控制台,您应该能够看到返回内容的属性。

console.log( myObj.doSome("task") ); // Expand the returned object in the
                                     //   console to see its properties.

UPDATE (As of ECMAScript6):-

更新(从 ECMAScript6 开始):-

The .then()function has been included to pure javascript.

.then()函数已包含在纯 javascript 中。

From the Mozilla documentation here,

这里的 Mozilla 文档,

The then() method returns a Promise. It takes two arguments: callback functions for the success and failure cases of the Promise.

then() 方法返回一个 Promise。它需要两个参数:Promise 成功和失败案例的回调函数。

The Promise object, in turn, is defined as

Promise 对象又被定义为

The Promise object is used for deferred and asynchronous computations. A Promise represents an operation that hasn't completed yet, but is expected in the future.

Promise 对象用于延迟和异步计算。Promise 表示尚未完成但预计在未来完成的操作。

That is, the Promiseacts as a placeholder for a value that is not yet computed, but shall be resolved in the future. And the .then()function is used to associate the functions to be invoked on the Promise when it is resolved - either as a success or a failure.

也就是说,Promise充当尚未计算但将在将来解析的值的占位符。该.then()函数用于关联在 Promise 解决时要在 Promise 上调用的函数 - 无论是成功还是失败。

回答by Magnus

Here is a thing I made for myself to clear out how things work. I guess others too can find this concrete example useful:

这是我为自己制作的东西,以弄清楚事情是如何运作的。我想其他人也会发现这个具体的例子很有用:

doit().then(function() { log('Now finally done!') });
log('---- But notice where this ends up!');

// For pedagogical reasons I originally wrote the following doit()-function so that 
// it was clear that it is a promise. That way wasn't really a normal way to do 
// it though, and therefore Slikts edited my answer. I therefore now want to remind 
// you here that the return value of the following function is a promise, because 
// it is an async function (every async function returns a promise). 
async function doit() {
  log('Calling someTimeConsumingThing');
  await someTimeConsumingThing();
  log('Ready with someTimeConsumingThing');
}

function someTimeConsumingThing() {
  return new Promise(function(resolve,reject) {
    setTimeout(resolve, 2000);
  })
}

function log(txt) {
  document.getElementById('msg').innerHTML += txt + '<br>'
}
<div id='msg'></div>

回答by Tarandeep Singh

Here is a small JS_Fiddle.

这是一个小的JS_Fiddle。

thenis a method callback stack which is available after a promise is resolved it is part of library like jQuery but now it is available in native JavaScript and below is the detail explanation how it works

then是一个方法回调堆栈,在解决承诺后可用它是像 jQuery 这样的库的一部分,但现在它在原生 JavaScript 中可用,下面是它如何工作的详细说明

You can do a Promise in native JavaScript : just like there are promises in jQuery, Every promise can be stacked and then can be called with Resolve and Reject callbacks, This is how you can chain asynchronous calls.

您可以在原生 JavaScript 中执行 Promise:就像 jQuery 中的 Promise 一样,每个 Promise 都可以堆叠,然后可以使用 Resolve 和 Reject 回调进行调用,这就是您可以链接异步调用的方式。

I forked and Edited from MSDN Docs on Battery charging status..

我从 MSDN 文档中分叉并编辑了电池充电状态..

What this does is try to find out if user laptop or device is charging battery. then is called and you can do your work post success.

这样做是尝试找出用户笔记本电脑或设备是否正在为电池充电。然后被调用,你可以在成功后做你的工作。

navigator
    .getBattery()
    .then(function(battery) {
       var charging = battery.charging;
       alert(charging);
    })
    .then(function(){alert("YeoMan : SINGH is King !!");});

Another es6 Example

另一个 es6 示例

function fetchAsync (url, timeout, onData, onError) {
    …
}
let fetchPromised = (url, timeout) => {
    return new Promise((resolve, reject) => {
        fetchAsync(url, timeout, resolve, reject)
    })
}
Promise.all([
    fetchPromised("http://backend/foo.txt", 500),
    fetchPromised("http://backend/bar.txt", 500),
    fetchPromised("http://backend/baz.txt", 500)
]).then((data) => {
    let [ foo, bar, baz ] = data
    console.log(`success: foo=${foo} bar=${bar} baz=${baz}`)
}, (err) => {
    console.log(`error: ${err}`)
})

Definition :: then is a method used to solve Asynchronous callbacks

this is introduced in ES6

Please find the proper documentation here Es6 Promises

定义 :: then 是一种用于解决异步回调的方法

这是在ES6 中引入的

请在此处找到正确的文档Es6 Promises

回答by hvgotcodes

I suspect doSome returns this, which is myObj, which also has a then method. Standard method chaining...

我怀疑 doSome 返回这个,它是 myObj,它也有一个 then 方法。标准方法链...

if doSome is not returning this, being the object on which doSome was executed, rest assured it is returning some object with a then method...

如果 doSome 没有返回 this,作为执行 doSome 的对象,请放心,它正在使用 then 方法返回某个对象...

as @patrick points out, there is no then() for standard js

正如@patrick 指出的那样,标准 js 没有 then()

回答by Hardeep SINGH

doSome("task")must be returning a promise object , and that promise always have a then function .So your code is just like this

doSome("task") 必须返回一个 promise 对象,并且该 promise 总是有一个 then 函数。所以你的代码就像这样

promise.then(function(env) {
    // logic
}); 

and you know this is just an ordinary call to member function .

你知道这只是对成员函数的普通调用。

回答by appdesigns

.thenreturns a promise in async function.

.then在异步函数中返回一个承诺。

Good Example would be:

好的例子是:

var doSome = new Promise(function(resolve, reject){
    resolve('I am doing something');
});

doSome.then(function(value){
    console.log(value);
});

To add another logic to it, you can also add the reject('I am the rejected param')call the function and console.log it.

要向它添加另一个逻辑,您还可以添加reject('I am the rejected param')调用函数和 console.log。

回答by appdesigns

In this case then()is a class method of the object returned by doSome()method.

在这种情况下then()是方法返回的对象的类doSome()方法。

回答by user2508620

The ".then()" function is wideley used for promised objects in Asynchoronus programming For Windows 8 Store Apps. As far as i understood it works some way like a callback.

“.then()”函数广泛用于 Windows 8 Store Apps 的异步编程中的承诺对象。据我了解,它的工作方式类似于回调。

Find Details in this Documentantion http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx

在此文档中查找详细信息 http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx

Of Cause it could also be the name for any other defined function.

当然,它也可以是任何其他已定义函数的名称。