根据我的理解,Promises的主要卖点之一是能够编写扁平代码(或者比回调地狱更平坦).
虽然看起来在很多情况下我们需要嵌套promises,以便使用闭包.例如(来自q的文档,虽然我使用Bluebird):
function authenticate() {
return getUsername()
.then(function (username) {
return getUser(username);
})
// chained because we will not need the user name in the next event
.then(function (user) {
return getPassword()
// nested because we need both user and password next
.then(function (password) {
if (user.passwordHash !== hash(password)) {
throw new Error("Can't authenticate");
}
});
});
}
Run Code Online (Sandbox Code Playgroud)
有没有更简洁的方法来做到这一点,没有嵌套?
编辑:我已经设法清理这个具体的例子使用.all,但有更复杂的情况,我不认为它可以做到:
function authenticate() {
return Promise.all([
getUsername().then(getUser),
getPassword()
]).spread(function (user, password) {
if (user.passwordHash !== hash(password)) { …Run Code Online (Sandbox Code Playgroud) 我正在使用直接的ES6 Promises(使用es6-promise polyfill库),我遇到了一个问题,即访问以前在链接中的承诺的结果.
这个问题在Angular/Q的背景下是相同的,但是我对答案不满意,并想看看是否有更好的方法:
请考虑以下代码段:
Student.find().then(function(student) {
return HelpRequest.findByStudent(student);
}, function(error) { //... }
).then(function(helpRequest) {
// do things with helpRequest...
// PROBLEM: I still want access to student. How can I get access to it?
});
Run Code Online (Sandbox Code Playgroud)
在链式承诺中,我想使用student我在第一个承诺中得到的对象.但正如所写,这无法访问它.我有几个明显的选择:
我实际上不知道这是如何工作的,但另一个问题中的解决方案表明我可以调用then结果HelpRequest.findByStudent()和调用Promise.resolve内的组合结果Student.find().then.不过,我认为以下实现不起作用.
Student.find().then(function(student) {
var data = {student: student};
HelpRequest.findByStudent(student).then(function(helpRequest) {
data.helpRequest = helpRequest;
});
// PROBLEM: if HelpRequest.findByStudent(student) is asynchronous, how
// does this get the data before returning?
return …Run Code Online (Sandbox Code Playgroud)我在节点中使用 babel 的require 钩子来利用 ES6,但我在 bluebird 承诺链中遇到了箭头函数的一些挑战。
我.bind({})在我的承诺链的顶部使用一个空对象来创建共享状态,我可以在其中存储以前的值,直到我在链的下游需要它们为止。Bluebird 将这种用法解释为“有用的副目的”。
当我切换到箭头的功能,我不能再因为箭头函数使用词汇使用共享状态this,其是undefined在巴别(巴别在严格模式下自动运行)。
工作示例:https : //jsbin.com/veboco/edit?html,js,console
ES6 示例(不工作):https ://jsbin.com/menivu/edit?html,js,console
在这种情况下,有没有办法利用箭头函数?在我的代码中,我从一个对象方法中调用这些方法 - 不this应该定义为调用该方法的对象吗?
function f () {
return new Promise(function (resolve, reject) {
resolve(4);
})
}
function g () {
return f().then((res) => {return res;})
}
console.log(g());
Run Code Online (Sandbox Code Playgroud)
这返回 Promise { <pending> }
如果我返回res(当时)然后返回f(),为什么不是输出4?
哪一个更有意义
var myVar = null;
myVar = someLogic(); //someLogic() might return a primitive or an object
if(myVar){
//other logic
}
Run Code Online (Sandbox Code Playgroud)
要么
var myVar;
myVar = someLogic(); //someLogic() might return a primitive or an object
if(myVar){
//other logic
}
Run Code Online (Sandbox Code Playgroud) 互联网上的每个提取API示例都展示了如何使用response.json(),response.blob()等仅返回主体。我需要的是同时调用内容类型和主体为blob的函数,而我无法弄清楚该怎么做。
fetch("url to an image of unknown type")
.then((response) => {
return {
contentType: response.headers.get("Content-Type"),
raw: response.blob()
})
.then((data) => {
imageHandler(data.contentType, data.raw);
});
Run Code Online (Sandbox Code Playgroud)
这显然行不通:data.contentType已填充,但data.raw是一个承诺。如何在相同的上下文中获得两个值?
我正在尝试清理我的 Parse Cloud Code 函数以使其更易于维护。为此,我尝试使用 Promises,但无法消除错误。
这是我的代码的目的:
Parse.Cloud.useMasterKey();
var action = request.object.get("action");
var from = request.object.get("from");
var to = request.object.get("to");
var reward = request.object.get("reward");
// Query 'from User' to decrement his score
var queryScore = new Parse.Query(Parse.User);
queryScore.get(from.id, {
success: function(score)
{
// Decrement score of 'fromUser'.
var newScore = score.get("score");
newScore -= reward;
score.set("score", newScore);
score.save(null, {
success: function(success)
{
// Score was saved.
// Find devices …Run Code Online (Sandbox Code Playgroud) 所以我有一个承诺链,解决了我遇到的某个回调地狱.
这是链条的样子:
server.exchange(oauth2orize.exchange.password(
function(client, email, password, scope, done) {
users.findOne({email: email})
.then(authenticateUser) // mix in password here?
.then(deleteExistingTokens)
.then(createAndSaveNewTokens)
.then(function(results){
done(null, results[0], results[1], {'expires_in': tokenLife});
}).catch(err => {done(err);});
}));
Run Code Online (Sandbox Code Playgroud)
所以users.findOne返回一个返回我的用户的promise.我需要'混合'密码进行身份验证.鉴于这是我对authenticateUser的定义,我将如何在链中插入新变量?
const authenticateUser = (err, user) => { // add password here?
return Promise((resolve, reject) => {
if (!user) {
reject('User not found');
}
try {
return User(user).authenticate(password)
.then((result) => {
if (result) {
resolve(user);
} else {
reject('Invalid password');
}
});
}
catch (err) {
reject('Invalid user');
} …Run Code Online (Sandbox Code Playgroud) 所以,我有4项任务:getStatus(),updateStatus(A),getTask(),updateTask(),它应该以这种方式执行:
getStatus(function(status) {
// A
updateStatus(status, function(status) {
// B
getTask(function(task) {
// C
updateTask(task, function(task) {
// D
})
})
})
})
Run Code Online (Sandbox Code Playgroud)
所以为了避免回调地狱,我用了诺言,现在所有这四个任务都返回了一个Promise,然后我改成了这个方式
getStatus().then(function(status) {
// A
updateStatus(status).then(function(status) {
// B
getTask().then(function(task) {
// C
updateTask(task).then(function(task) {
//D
})
})
})
})
Run Code Online (Sandbox Code Playgroud)
如你所见,它仍然有then hell,
我对Promise做错了吗?
当客户端提取请求导致服务器端出错时,我想返回错误代码(400)和自定义消息.我不知道如何使用fetch和promises优雅地在客户端检索这两者.
return fetch('/api/something')
.then(response => response.json())
.then(json => {
console.log(json.message)
// I only have access to the json here.
// I'd also like to get the response status code
// (from the response object) and potentially
// throw an error complete with the custom message.
})
.catch(function(ex) {
console.log('Unhandled Error! ', ex);
});
Run Code Online (Sandbox Code Playgroud)
谢谢!
我正在使用 Selenium 和 JavaScript 编写测试。我对两者都是新手,对函数式编程和 promise 也是新手。我正在尝试创建一个需要做 3 件事的函数:
我当前的功能不起作用:
var clearAndSendKeys = function(driver, elementIdentifier, sendKeys) {
var returnValue;
driver.findElement(elementIdentifier).then(function(inputField){
inputField.click().then(function() {
inputField.clear().then(function() {
returnValue = inputField.sendKeys(sendKeys);
});
});
});
return returnValue;
}
Run Code Online (Sandbox Code Playgroud)
然后将调用该函数,例如:
clearAndSendKeys(driver, webdriver.By.id('date_field'), '14.09.2015').then(function(){
//Do stuff
});
Run Code Online (Sandbox Code Playgroud)
我希望变量returnValue包含来自sendKeys. 但是,该函数clearAndSendKeys在运行 sendKeys 之前返回未定义的变量。我认为这是因为returnValue从未定义为承诺,因此程序不知道它需要等待sendKeys.
我怎样才能让我的函数clearAndSendKeys从 返回承诺sendKeys?我宁愿避免向clearAndSendKeys函数添加回调。
编辑:.then({return data})从代码中删除,因为这是一个错字。
我正在尝试链接嵌套.then函数并调用成功函数,但回调是在启动时调用.
//public method fn
function fn(callback) {
//calling the 1st API request
fn1()
.then(function(response) {
//2nd API request function
call1(response);
}, function(error) {
return $q.reject({
responseStatus: error.status
});
})
// Returning response
.then(function(response) {
callback({
responseStatus: 200
});
}, function(error) {
callback({
responseStatus: 500
});
});
}
function call1(response) {
//2nd API
fn2()
.then(function(response) {
//3rd API request function
call2(response);
}, function(error) {
return $q.reject({
responseStatus: error.status
});
});
}
function call2(response) {
//3rd API request
fn3()
.then(function(response) {
return …Run Code Online (Sandbox Code Playgroud) 根据node-fetch文档node-fetch
我们可以得到这样的响应状态
fetch('https://github.com/')
.then(res => {
console.log(res.status);
});
Run Code Online (Sandbox Code Playgroud)
并获取数据
fetch('https://api.github.com/users/github')
.then(res => res.json())
.then(jsonData => console.log(jsonData));
Run Code Online (Sandbox Code Playgroud)
我有一个场景,我需要从响应中返回JSON数据和状态.我试着这样用
fetch('https://api.github.com/users/github')
.then(res => res.json())
.then(jsonData => {
console.log(jsonData);
console.log(jsonData.status);
});
Run Code Online (Sandbox Code Playgroud)
但是
执行console.log(jsonData.status)
不会返回状态.我如何获得状态和输出数据
javascript ×11
promise ×7
ecmascript-6 ×4
bluebird ×3
fetch ×3
node.js ×3
es6-promise ×2
angularjs ×1
chaining ×1
node-fetch ×1
q ×1
return ×1
selenium ×1