Javascript 获取对早期承诺中变量的访问权限
基本上,在下面的脚本中,我想知道是什么URL被请求导致失败状态 我是否需要将其封装在一个对象中,并继续向下游传递它Javascript 获取对早期承诺中变量的访问权限,javascript,node.js,promise,q,Javascript,Node.js,Promise,Q,基本上,在下面的脚本中,我想知道是什么URL被请求导致失败状态 我是否需要将其封装在一个对象中,并继续向下游传递它 var Q = require('q') var _ = require('underscore') var JSON = require('JSON') var FS = require("q-io/fs"); var HTTP = require("q-io/http"); FS.read('members.json').then(function(memberJson){
var Q = require('q')
var _ = require('underscore')
var JSON = require('JSON')
var FS = require("q-io/fs");
var HTTP = require("q-io/http");
FS.read('members.json').then(function(memberJson){
return JSON.parse(memberJson)
}).then(function(memberObjects){
var httpCheckPromises = _.chain(memberObjects)
.first(50)
.filter(function(member){
return member.website.toLowerCase().indexOf('www') >= 0
})
.map(function(member){
return HTTP.read(member.website)
})
.value()
return Q.allSettled(httpCheckPromises)
}).then(function(responses){
return _.chain(responses)
.where({state:'rejected'})
.pluck('reason')
.pluck('response')
.value() ;
}).then(function(badResponses){
return _.chain(badResponses)
.filter(function(response) {
return response
})
.map(function(response){
return {
status: response.status
, headers: response.headers
}
})
.value()
}).then(function(responses){
return FS.write("members_with_bad_urls.json", JSON.stringify(responses,null,4))
}).then(function(){
console.log('DONE!')
}).fail(function(reason){
console.log('FAIL!')
console.log(reason)
})
例如,在我的第二个代码块中,add返回一个对象
then(function(memberObjects){
var httpCheckPromises = _.chain(memberObjects)
.first(50)
.filter(function(member){
return member.website.toLowerCase().indexOf('www') >= 0
})
.map(function(member){
return {
url: member.website
,response: HTTP.read(member.website)
}
})
.value()
return Q.allSettled(httpCheckPromises)
})
但是我想我可能会遇到需要重写的Q.allselled问题。我正在从随请求一起移动的response.node.req对象中提取原始HTTP请求。不幸的是,这不是对我最初问题的回答,而是对我问题的解决。不幸的是,我引用了一个用下划线表示的变量,这让我有点紧张。对于我正在运行的一个简单的脚本来说,OK-DBONCE不是一个很好的解决方案
then(function(badResponses){
return _.chain(badResponses)
.filter(function(response) {
return response
})
.map(function(response){
var req = response.node.req
return {
requestUri: req._headers.host + req.path
, httpStatusDesc: friendlyHttpStatus(response.status)
, httpStatus: response.status
, movedTo: response.headers.location
}
})
.value()
})
Akaphenom,为了使结果在整个过程中可用,您可以始终使用一个或多个外部变量,但使用这种类型的模式可能更干净:
promise_returning_function().then(function(x) {
return { x: x } ;//this object will be passed all the way down the .then chain.
}).then(function(obj) {
//here you can read obj.x
obj.y = ...;//add result of this process to obj
//return obj;
}).then(function(obj) {
//here you can read obj.x and obj.y
obj.z = ...;//add result of this process to obj
//return obj;
}).done(function(obj) {
//here you can read obj.x and obj.y and obj.z
});
为了说明该模式,我只是在每个阶段向obj
添加了一个属性(根据问题中的代码),但您可以添加任意多个属性(无、一个或多个),无论后续阶段需要什么
不幸的是,通过这种方式传播obj
,失去了.then()
返回新承诺的能力。但是,模式的以下变体克服了这一问题:
promise_returning_function().then(function(x) {
var promise_x = ...;//do something asynchronous here
return Q.when(promise_x, function(result_x) {
return { x: result_x };//this object will be passed all the way down the .then chain.
});
}).then(function(obj) {
//here you can read obj.x
var promise_y = ...;//do something asynchronous here
return Q.when(promise_y, function(result_y) {
obj.y = result_y;
return obj;
});
}).then(function(obj) {
//here you can read obj.x and obj.y
var promise_z = ...;//do something asynchronous here
return Q.when(promise_z, function(result_z) {
obj.z = result_z;
return obj;
});
}).done(function(obj) {
//here you can read obj.x and obj.y and obj.z
});
也许这种模式可以称为“瀑布”
代码相当冗长,外部的var obj={}
当然会更简洁,但希望该模式有一些潜在的用途
编辑
这是一个,在这里我提取了重复代码并创建了一个助手函数propagate()
编辑2
和一个,每个阶段都有一个设置超时延迟
编辑3
这就是使用helper函数propagate()
哦,人-创造性的方法,比我正在考虑的选择要好得多。我有一个解决我当前问题的解决方案(尽管这种方法更好),在我的解决方案中提到了这个问题,并且它会在这个问题的一方采取措施。我打算再等一两天,看看我们是否能寻求更多的解决方案。一个模式,可能胜过千言万语。这真是一个超级答案。代码是干净的,它解决了一个问题,我希望它将成为prominant
function propagate(p, obj, prop) {
return Q.when(p, function(result) {
obj[prop] = result;
return obj;
});
}
promise_returning_function().then(function(x) {
var promise_x = ...; //do something asynchronous here
return propagate(promise_x, {}, 'x');
}).then(function(obj) {
//here you can read obj.x
var promise_y = ...; //do something asynchronous here
return propagate(promise_y, obj, 'y');
}).then(function(obj) {
//here you can read obj.x and obj.y
var promise_z = ...; //do something asynchronous here
return propagate(promise_z, obj, 'z');
}).done(function(obj) {
//here you can read obj.x and obj.y and obj.z
});