【发布时间】:2021-05-07 10:15:52
【问题描述】:
我看到的代码看起来像:
myObj.doSome("task").then(function(env) {
// logic
});
then() 来自哪里?
【问题讨论】:
-
更新:我发现它与 CommonJS 承诺 API sitepen.com/blog/2010/01/19/…
标签: javascript
我看到的代码看起来像:
myObj.doSome("task").then(function(env) {
// logic
});
then() 来自哪里?
【问题讨论】:
标签: javascript
在 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 提出以下建议:
promise 对象。promise 对象都有一个then 函数,它可以接受两个参数,一个success
处理程序和一个error 处理程序。then 函数中的成功或错误处理程序将仅被调用一次,之后
异步任务完成。then 函数还将返回 promise,以允许链接多个调用。value,它将传递给下一个
在promises 链中充当argument。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
}
);
传播成功和错误
链式 Promise 是一种非常强大的技术,它可以让我们完成很多
功能,例如让服务进行服务器调用,对
数据,然后将处理后的数据返回给控制器。但是当我们与
promisechains,有几点我们需要牢记。
考虑以下假设的promise 链,其中包含三个 Promise,P1、P2 和 P3。
每个promise 都有一个成功处理程序和一个错误处理程序,因此 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 中收到服务器的成功响应,但返回的数据不是 正确,或者服务器上没有可用数据(想想空数组)。在这样一个 在这种情况下,对于下一个 Promise P2,它应该触发错误处理程序 E2。
• 我们收到 Promise P2 的错误,触发 E2。但是在处理程序内部,我们有 缓存中的数据,确保应用程序可以正常加载。在这种情况下, 我们可能希望确保在 E2 之后调用 S3。
所以每次我们编写成功或错误处理程序时,我们都需要进行调用——给定我们的 当前函数,对于 Promise 中的下一个处理程序,这个 Promise 是成功还是失败 链?
如果我们想为链中的下一个 Promise 触发成功处理程序,我们可以 从成功或错误处理程序返回一个值
另一方面,如果我们想要触发错误处理程序以处理
链,我们可以使用deferred 对象并调用其reject() 方法来做到这一点
现在什么是延迟对象?
jQuery 中的延迟对象表示一个工作单元,它将被 稍后完成,通常是异步的。一旦工作单位 完成后,
deferred对象可以设置为已解决或失败。
deferred对象包含promise对象。通过promise对象 您可以指定当工作单元完成时会发生什么。你 通过在promise对象上设置回调函数来实现。
Jquery 中的延迟对象:https://api.jquery.com/jquery.deferred/
AngularJs 中的延迟对象:https://docs.angularjs.org/api/ng/service/$q
【讨论】:
then() 函数与一些库或框架(如 jQuery 或 AngularJS)中使用的“Javascript 承诺”有关。
promise 是一种处理异步操作的模式。 Promise 允许您调用一个名为“then”的方法,该方法允许您指定要用作回调的函数。
欲了解更多信息,请参阅:http://wildermuth.com/2013/8/3/JavaScript_Promises
对于 Angular 承诺:http://liamkaufman.com/blog/2013/09/09/using-angularjs-promises/
【讨论】:
A promise can only succeed or fail once 和If a promise has succeeded or failed and you later add a success/failure callback, the correct callback will be called
promise 以及如何使用callback
据我所知,javascript 中没有内置的 then() 方法(在撰写本文时)。
似乎无论doSome("task") 返回的是什么,都有一个名为then 的方法。
如果你将doSome()的返回结果记录到控制台,你应该可以看到返回的属性。
console.log( myObj.doSome("task") ); // Expand the returned object in the
// console to see its properties.
更新(从 ECMAScript6 开始) :-
.then() 函数已包含在纯 JavaScript 中。
来自 Mozilla 文档here,
then() 方法返回一个 Promise。它有两个参数:回调 Promise 成功和失败案例的函数。
Promise 对象又被定义为
Promise 对象用于延迟和异步 计算。 Promise 表示尚未完成的操作 还没有,但预计会在未来出现。
也就是说,Promise 充当尚未计算但将在未来解决的值的占位符。 .then() 函数用于关联 Promise 解决时要调用的函数 - 无论是成功还是失败。
【讨论】:
.then,但现在 ES6 中出现了原生承诺:html5rocks.com/en/tutorials/es6/promises
这是我为自己制作的东西,目的是弄清楚事情是如何运作的。我想其他人也会发现这个具体的例子很有用:
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>
【讨论】:
then 是一个方法回调堆栈,在 promise 解决后可用,它是 jQuery 等库的一部分,但现在它可以在原生 JavaScript 中使用,下面是它的工作原理的详细说明
你可以在原生 JavaScript 中做一个 Promise:就像 jQuery 中的 Promise 一样,每个 Promise 都可以堆叠,然后可以用 Resolve 和 Reject 回调调用,这就是你可以链异步调用的方式。强>
我从关于电池充电状态的 MSDN 文档中分叉和编辑..
它的作用是尝试找出用户笔记本电脑或设备是否正在为电池充电。然后被调用,您可以在成功后完成您的工作。
navigator
.getBattery()
.then(function(battery) {
var charging = battery.charging;
alert(charging);
})
.then(function(){alert("YeoMan : SINGH is King !!");});
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 Promises找到正确的文档
【讨论】:
then 的来源和工作原理。您应该改进您的答案以提供这些详细信息。
.then 在异步函数中返回一个承诺。
很好的例子是:
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')调用函数并控制台记录它。
【讨论】:
我怀疑 doSome 返回这个,即 myObj,它也有一个 then 方法。标准方法链...
如果 doSome 没有返回 this,它是执行 doSome 的对象,请放心,它正在使用 then 方法返回某个对象...
正如@patrick 指出的那样,标准 js 没有 then()
【讨论】:
{}:这 3 个示例在做同样的事情(什么都没有,但有有效的语法,并且是一个有效的 Promise 链!)
new Promise(function(ok) {
ok(
/* myFunc1(param1, param2, ..) */
)
}).then(function(){
/* myFunc1 succeed */
/* Launch something else */
/* console.log(whateverparam1) */
/* myFunc2(whateverparam1, otherparam, ..) */
}).then(function(){
/* myFunc2 succeed */
/* Launch something else */
/* myFunc3(whatever38, ..) */
})
console.log("This code has no errors 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!")
带有{}的箭头函数
new Promise( (ok) => {
ok(
/* myFunc1(param1, param2, ..) */
)
}).then( () => {
/* myFunc1 succeed */
/* Launch something else */
}).then( () => {
/* myFunc2 succeed */
/* Launch something else */
/* myFunc3(whatever38, ..) */
console.log("something")
/* More console logs! */
console.log("something else")
})
console.log("This code has no errors GG!")
【讨论】:
doSome("task") 必须返回一个promise 对象,并且该promise 总是有一个then 函数。所以你的代码就是这样
promise.then(function(env) {
// logic
});
你知道这只是对成员函数的普通调用。
【讨论】:
这里then()是doSome()方法返回的对象的类方法。
【讨论】:
“.then()”函数广泛用于 Asynchoronus 编程中的承诺对象,用于 Windows 8 商店应用程序。 据我了解,它的工作方式类似于回调。
在本文档中查找详细信息 http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx
当然,它也可以是任何其他已定义函数的名称。
【讨论】:
我迟到了大约 8 年,嗯...无论如何,我真的不知道 then() 做了什么,但也许 MDN 可能会有答案。其实,我可能会更了解它。
这将向您显示您需要的所有信息(希望如此)。除非有人已经发布了这个链接。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
格式为promise.prototype.then() 承诺和原型有点像变量,但不像 javascript 中的变量,我的意思是像 navigator.getBattery().then() 之类的其他东西,其中这个实际上存在但几乎没有在网络上使用,这个显示状态如果您对设备的电池感到好奇,请访问 MDN 了解更多信息和更多信息。
【讨论】: