我看到的代码是这样的:

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

那么()从何而来?


我猜doSome会返回这个,也就是myObj,它也有then方法。标准方法链接…

如果doSome不返回this,作为doSome执行的对象,请放心,它将返回具有then方法的某个对象…

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


截至ECMAScript6

.then()方法已经包含在纯JavaScript的Promises中。

来自Mozilla文档:

then()方法返回一个Promise。它有两个参数:callback 有关承诺成功及失败个案的功能。

Promise对象定义为

Promise对象用于延迟和异步 计算。Promise表示未完成的操作 然而,但在未来是值得期待的。

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

ECMAScript6之前

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

无论doSome(“task”)返回的是什么,似乎都有一个调用then的方法。

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

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

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


".then()"函数广泛用于Windows 8 Store应用程序异步编程中的承诺对象。 据我所知,它在某种程度上像一个回调。

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

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


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

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

欲了解更多信息,请参阅:http://wildermuth.com/2013/8/3/JavaScript_Promises

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


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

在本例中,我们首先获取服务器配置。在此基础上,我们进行取回 关于当前用户的信息,最后获取当前用户的项目列表 用户。每个xhrGET调用都接受一个回调函数,该函数在服务器 响应。

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

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

Promise API提出以下建议:

Each asynchronous task will return a promise object. Each promise object will have a then function that can take two arguments, a success handler and an error handler. The success or the error handler in the then function will be called only once, after the asynchronous task finishes. The then function will also return a promise, to allow chaining multiple calls. 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. 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.

因此,前面的示例代码可以转换为以下内容,使用 promises和$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
    }
);

传播成功和错误

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

考虑以下假设的承诺链,其中有三个承诺,P1、P2和P3。 每个承诺都有一个成功处理程序和一个错误处理程序,S1和E1对应P1 S2和 P2为E2, P3为S3和E3:

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

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

考虑以下情况:

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

•我们收到承诺P2的错误,触发了E2。但在处理器内部,我们有 缓存中的数据,确保应用程序可以正常加载。这样的话, 我们可能想要确保在E2之后,S3被调用。

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

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

类中的下一个promise触发错误处理程序 Chain,我们可以使用一个deferred对象并调用它的reject()方法来实现

什么是递延对象? 在jQuery中,延迟对象表示将被延迟的工作单元 稍后完成,通常是异步完成。一旦单位的工作 完成时,可将延迟对象设置为已解决或失败。 deferred对象包含promise对象。通过promise对象 您可以指定当工作单元完成时将发生什么。你 通过在promise对象上设置回调函数来实现。

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

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


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

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

这只是一个普通的成员函数调用。


这是一个小的JS_Fiddle。

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

你可以在原生JavaScript中做一个承诺:就像在jQuery中有承诺一样,每个承诺都可以堆叠,然后可以用Resolve和Reject回调调用,这就是你如何链式异步调用。

我从MSDN文档中分叉和编辑电池充电状态。

这是试图找出用户的笔记本电脑或设备是否正在充电电池。然后是叫你和你的工作成功后。

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

另一个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}`)
})

then是一个用于解决异步回调的方法 这是在ES6中引入的 请在这里找到适当的文件Es6承诺


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

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>


我大概晚了8年,嗯……不管怎样,我真的不知道then()做什么,但也许MDN可能有一个答案。实际上,我可能更懂一点。

这将向您显示所需的所有信息(希望如此)。除非有人已经发布了这个链接。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

格式为promise.prototype.then() promise和prototype有点像变量,但不像javascript中的变量,我的意思是像navigator。getbattery()。then()这样的东西,这个确实存在,但很少在网络上使用,这个显示设备电池的状态,如果你好奇,MDN上还有更多信息。


这是关于在箭头函数中使用花括号{}的问题:


这3个例子做的是同样的事情(什么都没有,但是有有效的语法,并且是一个有效的Promise链!)


新承诺(函数(ok) { ok ( /* myFunc1(param1, param2, ..) */ ) })(函数(){ /* myFunc1成功*/ /*启动其他内容*/ /* console.log(whateverparam1) */ /* myFunc2(whateverparam1, otherparam, ..) */ })(函数(){ /* myFunc2 succeed */ /*启动其他内容*/ /* myFunc3(whatever38, ..) */ }) console.log(“这段代码没有错误GG!”)


相同的逻辑使用箭头函数省略{}

new Promise((ok) => ok( /* myFunc1(param1, param2, ..) */ ).then(() => 0 // HEY DID YOU NOTICE! A number that does nothing, // but otherwise the parsing will fail! // The code is pretty clean but have a major downside // As arrow functions without {} can contains only one declaration // console.log("something") will FAIL here ).then(() => "" // HEY DID YOU NOTICE! An empty string that does nothing, // but otherwise the parsing will fail! // As arrow functions without {} can contains only one declaration // We can't add more code here, hence: // console.log("something") // Will break the whole promise // This is likely the error in y(our) code ;) )) console.log("This code has no errors GG!")


带有{}的箭头函数

新承诺((ok) => { ok ( /* myFunc1(param1, param2, ..) */ ) })。那么(()=> { /* myFunc1成功*/ /*启动其他内容*/ })。那么(()=> { /* myFunc2 succeed */ /*启动其他内容*/ /* myFunc3(whatever38, ..) */ console.log(“什么”) /*更多控制台日志!* / console.log(“其他东西”) }) console.log(“这段代码没有错误GG!”)


.然后在async函数中返回一个promise。

好的例子是:

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

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

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