gpt4 book ai didi

javascript - 访问下游早期 promise 中的变量

转载 作者:行者123 更新时间:2023-11-30 17:33:36 25 4
gpt4 key购买 nike

基本上在下面的脚本中,我想知道导致失败状态的请求 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){
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)
})

例如在我的第二个代码块中添加返回一个对象

 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.allSettled 问题。

最佳答案

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 的能力就丢失了。然而,该模式的以下变体克服了这一点:

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

也许这种模式可以称为“.then waterfall ”?

代码相当冗长,外部 var obj = {}; 肯定会更简洁,但希望该模式有一些潜在用途。

编辑

这是一个 DEMO ,我在其中提取了重复代码并创建了一个辅助函数 propagate()

编辑2

还有一个 more convincing version of the DEMO 在每个阶段都有一个 setTimeout 延迟。

编辑3

这是带有辅助函数 propagate() 的模式的样子

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

关于javascript - 访问下游早期 promise 中的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22485646/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com