【问题标题】:How to handle Promise in nodejs如何在 nodejs 中处理 Promise
【发布时间】:2017-07-26 02:21:20
【问题描述】:

我正在尝试在 nodejs 中执行回调函数,使用 expressjs 和 angular 2(我不知道 angular2 部分是否相关)。

我所做的是: 我在 angular2 中有一个公式,我向我的 API 路由发送一个 get 请求,然后我通过 get 将公式中的文本字段发送到 URL,然后我执行 MYSQL 查询以查看电话簿数据库,然后我我希望从电话簿中获得完整的用户及其详细信息。

公式:

<div class="container">
<div class="col-md-4">
<h1>Addressbook</h1>
<form [formGroup]="searchForm" (ngSubmit)="doSearch($event)">
<input formControlName="searchString" type="text" placeholder="Name">
<button type="submit">Search</button>
</form>
</div>
</div>

第一个函数,doSearch:

doSearch(event) {
    let formData = this.searchForm.value;
    var searchString = this.searchForm.value.searchString;

    this.http.get('/phonebook/search/'+searchString, function(req, res){}).subscribe(
    function(response) {
    console.log("Success Response");
    },
    function(error) { console.log("Error happened" + error)},
    function() { console.log("the subscription is completed")}
    );
}

这会调用发送参数的路由,所以并不难。

现在创建路由器进入游戏:

public static create(router: Router, basePath: string) {
    console.log("[SearchRoute::create] Creating routes for /search.");
    // call the function for retrieving the address book results
    router.get(basePath + "/search/:searchString", (req: Request, res: Response, next: NextFunction) => {
    console.log("##  [SearchRoute] Called GET /search.");
    var object = searchUser(req);
    console.log(object);
        });
}

最后,函数 searchUser 被调用:

function searchUser(req: Request) {

    console.log("searchUser Function executed.");

    var searchString = req.params.searchString;

    var query = p_query('SELECT XXXX')
    .then(function (results) {
    console.log("query executed and all okay");
    return (results);
    })
    .catch(function (error) {
    console.error("Wooopsi", error);
    });

    console.log("query result: "+query);
}

此外,我在这里发布了我构建的新查询函数,以便能够处理承诺(我不知道它是否是最佳选择):

function p_query(q) {
    return new Promise(function (resolve, reject) {
    // The Promise constructor should catch any errors thrown on
    // this tick. Alternately, try/catch and reject(err) on catch.
    myMYSQL.db.query(
    q,
    function (error, results) {
    if (error)
    reject(error);
    resolve(results);
    });
    })
};

那么,我真正想做的是什么,我的问题是什么?

我想将查询结果发送回客户端(angular2 公式),但我无法做到...

因此,在这篇非常长的帖子之后,如果您阅读到这里,我真的很感激,对于这个复杂的问题,我深表歉意!

PS:我知道我对自己的解释很糟糕:(

问候, 丹尼尔

【问题讨论】:

  • 有必要使用promise吗?
  • 在这种情况下可能不是,但是我在另一个函数中遇到了我需要执行一个查询的情况,该查询取决于第一个查询的结果(在第一个查询中,我查找客户端 ID ,并且我在第二个查询中使用该客户端 ID),当我将它们放在同一个代码块中时,有时它们会同时执行并且第二个查询失败(因为首先执行),所以对于这种情况可能不是,但我会真的很喜欢用它
  • 你在哪里? res.json(object) 在你的路由器定义中?然后在您的 doSearch 中,您必须处理接收到的数据,例如response.body?
  • 您可以使用递归回调将它们全部包装在函数中,一个函数将在得到结果后执行另一个函数?
  • @Myonara 我是 nodejs 的一个完整的菜鸟,如果你能给我一个链接,我可以阅读该对象。

标签: mysql node.js angular express


【解决方案1】:

official angular 2 documentation on the http client 中,他们建议将 http 逻辑放入单独的服务中。我已将其设置为类似于仅用于 search.service.ts 的示例:

import { Injectable } from '@angular/core';
import { Http, Response,Headers, RequestOptions,URLSearchParams }
          from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';

@Injectable()
export class SearchService {
    constructor(private http: Http) { 
    }

    getSearchResult(searchString)  : Observable<any>  {
        return this.http.get('/phonebook/search/'+searchString)
         .map(this.extractData)
         .catch(this.handleError);
    }

    private extractData(res: Response) {
        let body = res.json();
        return body;
    }
    private handleError (error: Response | any) {
        let errMsg: string;
        if (error instanceof Response) {
            const body = error.json() || '';
            const err = body.error || JSON.stringify(body);
            errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
        } else {
            errMsg = error.message ? error.message : error.toString();
        }
        return Observable.throw(errMsg);
    }
}

在您的组件中导入服务并执行代码 sn-ps:

// don't forget to put the service in the app.modul or the component providers!
  constructur(public mySearchService : SearchService) {}

// in your doSearch of your component:
   doSearch(event) {
    let formData = this.searchForm.value;
    var searchString = this.searchForm.value.searchString;
    mySearchService.getSearchResult(searchString).subscribe(
        data => mylist.data, // or which datastructure I want to write to.
        error => console.error(error) // or how I log the errors..
    );
   }

编辑:您的数据库模型中的 search_user:

function searchUser(searchString) {
   console.log("searchUser Function executed.");
   return myMYSQL.db.select('phonebookentry', {
        pbe_lastname: searchString, pbe_syncstate: 'new'
   }) // returning the promise/observable to the main function...
} // Currently I don't know, how the returned data looks like.

the router 的节点/快递端使用res.json 发送它编辑:使用异步调用搜索用户

router.get(basePath + "/search/:searchString", 
    (req: Request, res: Response, next: NextFunction) => {
    console.log("##  [SearchRoute] Called GET /search.");
    searchUser(req)
     .then( data => res.json(data);console.log(data) )
     .catch (error => console.log(error));
    });

【讨论】:

  • 我在帖子中添加了另一个答案,你帮了我很多,只是缺少最后一个功能!非常感谢
  • 我发现的第二件事:我的组件(角度应用程序)和服务(处理搜索的那个)是完全分开的,所以导入服务的 doSearch 步骤不起作用太好了,因为 mysearchservice 它在服务端......我不知道我是否解释得这么好
  • 感谢您的解决方案!
【解决方案2】:

您应该在每个查询结果中使用递归回调,尝试享受异步平台的美妙。 通过

向客户端发送数据
res.send(data);

【讨论】:

  • 好吧,这很重要,我会这样做。但问题是,我怎样才能将对象发送回客户端?这是我缺少的部分
  • 您可以创建一个空变量并在每次查询后向其中添加数据,最后您可以通过路由器的响应实例向客户端发送数据
【解决方案3】:

你的回答很完美,我什么都懂!我现在面临的唯一问题,就是这个:

我正在调用函数 searchUser,它没有返回任何东西,只是一个未定义的对象,所以我怀疑我没有正确地返回。

这是我的 searchUser 函数:

function searchUser(searchString) {

console.log("searchUser Function executed.");

myMYSQL.db.select('phonebookentry', {
pbe_lastname: searchString,
pbe_syncstate: 'new'
}).then(function (user) {
console.log("user before: "+user);
return (user);
}).catch(function (err) {
console.log(err);
})}

非常感谢您的有用回答!快到这里了

【讨论】:

  • 哦,node 的 DB 端的 searchUser 也是异步的,今天晚上我会扩展我的答案来涵盖这个。
  • 完美,非常感谢,如果您需要任何其他文件、信息或其他任何内容,请索取。非常感谢您花时间帮助我!
  • 我已经编辑了我的答案并标记了 EDIT。我不知道的是,您的数据库的输出在 then/Catch 路径中的样子。
猜你喜欢
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 2021-06-11
  • 2021-05-09
  • 2018-03-26
  • 1970-01-01
  • 2021-06-05
  • 2020-08-30
相关资源
最近更新 更多