Javascript承诺无法按预期工作

AH.*_*AH. -2 javascript ecmascript-6 es6-promise

在这里,我宣布了我的承诺

   const fetchmessage= new Promise(
            (resolve,reject)=>{
              this.props.authStore.verifyLocalToken();
              console.log("VLT Resolve");
              resolve("Completed");
            }
            );

          fetchmessage.then(this.props.inboxStore.inboxMessageFetch(mobileNumber,firebaseToken));
Run Code Online (Sandbox Code Playgroud)

以下是我的verifyLocalToken代码

   verifyLocalToken() {
    console.log("VerifyLT - Start");
        fetch('http://xxx.xxx.xxx.xxx:8000/api/VerifyLocalToken', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            body: `mobileNumber=${this.mobileNumber}&key=${this.key}`
        }).then((response) => response.json()).then(
            (responseJson) => {
                console.log("http request v l t --", responseJson);
                this.firebaseToken = responseJson.firebaseToken;
            }).catch(
            (error) => {
                console.error(error);
            }
        )
        console.log("VerifyLT - Stop");

}
Run Code Online (Sandbox Code Playgroud)

以下是我的inboxMessageFetch代码

inboxMessageFetch(mobileNumber,firebaseToken) {
        console.log("InboxFetch  --", `${mobileNumber}/inbox`,firebaseToken);

            firebase.database().ref(`${mobileNumber}/inbox`)
                .on('value', snapshot => {
                    console.log('FB', snapshot.val());
                })
    }
Run Code Online (Sandbox Code Playgroud)

输出是这样的 控制台日志

不应该 在InboxFetch之前提出http请求vlt - 8891468710/inbox undefined,因为HTTP请求属于我们要求在获取HTTP请求后运行的promise和收件箱提取?

如何重构代码并确保完成HTTP请求,然后调用收件箱获取功能?

T.J*_*der 5

这里有几个问题.

  1. 这条线

    fetchmessage.then(this.props.inboxStore.inboxMessageFetch(mobileNumber,firebaseToken));
    
    Run Code Online (Sandbox Code Playgroud)

    ... 调用 this.props.inboxStore.inboxMessageFetch(mobileNumber,firebaseToken)并将其返回值传递给then,就像foo(bar()) 调用 一样bar,然后将其返回值传递给foo.你可能想要传递一个函数,例如

    fetchmessage.then(() => this.props.inboxStore.inboxMessageFetch(mobileNumber,firebaseToken));
    
    Run Code Online (Sandbox Code Playgroud)
  2. verifyLocalToken在继续执行之前,你不是在等待异步工作fetchmessage.

  3. (与#2相关)verifyLocalToken没有为调用者提供任何方式来知道它的工作已经完成; 它需要回报一个承诺.

  4. (相关#2#3)你已经有一个承诺,从fetchverifyLocalToken; 所以没有必要创建一个新的保存承诺fetchmessage.任何时候你有一个承诺,使用then,不要使用new Promise反模式.

  5. fetchmessage 对我来说听起来像一个函数名,但在你的代码中,它是一个接收promise而不是函数的变量.

这是大概应该看的东西(注意***评论):

verifyLocalToken() {
    console.log("VerifyLT - Start");
    // *** Return the promise from `then`
    return fetch('http://xxx.xxx.xxx.xxx:8000/api/VerifyLocalToken', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: `mobileNumber=${this.mobileNumber}&key=${this.key}`
    }).then((response) => response.json()).then(
        (responseJson) => {
            console.log("http request v l t --", responseJson);
            this.firebaseToken = responseJson.firebaseToken;
        }).catch(
        (error) => {
            console.error(error); // *** You're converting failure to success
                                  // with `undefined` here, which isn't
                                  // a good idea. Re-throw the error.
            throw error;
        })
    // *** If you want to show something when this finishes, do it
    // in a `then` handler
    ).then(value => {
        console.log("VerifyLT - Stop");
        return value;
    });
}
Run Code Online (Sandbox Code Playgroud)

然后fetchmessage:

const fetchmessage = this.props.authStore.verifyLocalToken()
    .then(value => {
        console.log("VLT Resolve");
        return "Completed"; // *** Really convert the value to completed?
    });
Run Code Online (Sandbox Code Playgroud)

...如果你想将呼叫分开then:

fetchmessage.then(result => this.props.inboxStore.inboxMessageFetch(mobileNumber, firebaseToken));
Run Code Online (Sandbox Code Playgroud)

这是你需要做的草图,不是直接复制和粘贴的.通过思考并根据需要应用它们.

请记住,promises是一个管道,每个处理程序在它经历时转换值.