gpt4 book ai didi

javascript - 在 nodejs 中遇到 promise 问题

转载 作者:行者123 更新时间:2023-11-30 07:42:39 26 4
gpt4 key购买 nike

我正在尝试将 promises 与 nodejs 一起使用(我正在尝试使用 node-promise 包);然而,没有任何成功。请看下面的代码:

var express = require('express'),
request = require('request'),
promise = require('node-promise');

app.get('/promise', function(req, res) {
var length = -1;

new promise.Promise(request(
{uri: "http://www.bing.com"},
function (error, response, body) {
if (error && response.statusCode !== 200) {
console.log("An error occurred when connected to the web site");
return;
}

console.log("I'll return: " + body.length);
length = body.length;
}
)).then(function(result) {
console.log("This is what I got: " + length);
console.log("Done!");
});

res.end();
});

以上代码的输出是I'll return: 35857只有并且它不会转到 then部分。

然后我将代码更改为:

app.get('/promise', function(req, res) {
var length = -1;

promise.when(
request(
{uri: "http://www.bing.com"},
function (error, response, body) {
if (error && response.statusCode !== 200) {
console.log("An error occurred when connected to the web site");
return;
}

console.log("I'll return: " + body.length);
length = body.length;
}
),
function(result) {
console.log("This is what I got: " + length);
console.log("Done!");
},
function(error) {
console.log(error);
}
);

res.end();
});

这次的输出是This is what I got: -1然后Done! ...看起来这次没有调用“ promise ”。

所以:

  • 需要做什么来修复上面的代码?显然我做的不对:)
  • 当我做出 promise 时,node-promise 是“要走的路”,还是有更好的方法/包?即更简单,更适合生产。

谢谢。

最佳答案

尝试 jquery-deferred-for-node .

我不是专家,但我知道这个库往往受到同时在服务器端和客户端工作的程序员的青睐。

即使您还不知道 jQuery 的 Deferreds,走这条路的好处是:

  • 文档非常好(它包含指向 jQuery 文档的链接),但您可能很难找到特定于 Node 的示例。

  • 方法是可链接的。

  • jQuery 回调 也包括在内。

  • 当有一天您需要在客户端执行异步操作时,几乎没有什么需要重新学习的 - 概念完全相同,语法也几乎完全相同。请参阅上面超链接的 github 页面中的“通信”部分。

编辑

我不是 node.js 的人,所以我在这里猜测,但根据您上面的代码,您可能需要考虑以下几行 jquery-deferred-for-node :

var express = require('express'),
request = require('request'),
Deferred = require('JQDeferred');

function fetch(uri, goodCodes) {
goodCodes = (!goodCodes) ? [200] : goodCodes;

var dfrd = Deferred(); // A Deferred to be resolved/rejected in response to the `request()`.
request(uri, function(error, response, body) {
if (!error) {
var isGood = false;

// Loop to test response.statusCode against `goodCodes`.
for (var i = 0; i < goodCodes.length; i++) {
if (response.statusCode == goodCodes[i]) {
isGood = true;
break;
}
}

if (isGood) {
dfrd.resolve(response.statusCode, body);
} else {
dfrd.reject(response.statusCode, "An invalid response was received from " + uri);
}
} else {
dfrd.reject(response.statusCode, "An error occurred attempting to connect to " + uri);
}
});

// Make promise derived from dfrd available to "consumer".
return dfrd.promise();
};

//...

app.get('/promise', function(req, resp) {
fetch("http://www.bing.com").done(function(statusCode, result) {
console.log("Done! This is what I got: " + result.length);
}).fail(function(statusCode, message) {
console.log("Error (" + statusCode + "): " + message);
});
resp.end();
};

在这里,我尝试编写一个通用实用程序来获取资源,以便可以在外部处理异步响应(或错误)。我认为这大致符合您试图实现的目标。

出于兴趣,console.log() 消息在哪里以 node.js 结尾?

编辑2

在上面,我给了 Deferred 一个初始资本,这是构造函数的常规做法

对于 jQuery Deferreds,必须有任意数量的方法来连续获取 fetch()。下面的方法保留了 fetch() 的原样,并引入了 fetch_() 作为其前端。可能有更简单的方法,但这允许 fetch() 保持通用实用程序,在功能上等同于客户端 jQuery.ajax()

function fetch_(uri){
return function(){
return fetch(uri, [200]).then(function(statusCode, result){
console.log("Done! This is what I got: " + result.length);
},function(statusCode, message){
console.log("Error (" + statusCode + "): " + message);
});
};
}

请注意函数 fetch() 返回一个函数。它必须是这样的,因为在调用 fetch() 的地方,我们需要一个未执行的函数,而不是(还)该函数的结果。

现在让我们假设一个 uris 数组可用。这可以是硬编码的或动态构建的——无论应用程序需要什么。

var uris = [
'http://xxx.example.com',
'http://yyy.example.com',
'http://zzz.example.com'
];

现在,可以通过多种方式调用 fetch_():

//v1. To call `resp.end()` when the fetching process starts.
app.get('/promise', function(req, resp) {
fetch_(uris[0])().then(fetch_(uris[1])).then(fetch_(uris[2]));
resp.end();
});

//v2. To call `resp.end()` when the fetching process has finished.
app.get('/promise', function(req, resp){
fetch_(uris[0])().then(fetch_(uris[1])).then(fetch_(uris[2])).always(resp.end);
});

//v3. As v2 but building a `.then()` chain of any (unknown) length.
app.get('/promise', function(req, resp){
var dfrd = Deferred().resolve();//
$.each(uris, function(i, uri){
dfrd = dfrd.then(fetch_(uri));
});
dfrd = dfrd.always(resp.end);
});

未经测试

我对v1和v2更有信心。 v3 可能有效。

v2 和 v3 应该给出完全相同的行为,但 v3 被推广到任意数量的 uris。

一切都可能需要调试。

关于javascript - 在 nodejs 中遇到 promise 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13532478/

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