理解承诺(使用Bluebird和Node)

时间:2015-08-01 03:00:46

标签: node.js promise

我试图以正确的方式使用承诺&#34;,我对这种情况感到困惑。以下是两段代码。第一个完美运行,第二个失败。我认为他们应该以同样的方式工作,但他们不会。在两者中,都创建了两个记录,但 `package com.example.programacion.ventasje.Principal; import android.content.res.Resources; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentManager; import android.support.v4.app.Fragment; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.internal.widget.AdapterViewCompat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.example.programacion.ventasje.Cliente.Frm_Cliente; import com.example.programacion.ventasje.R; import java.util.ArrayList; /** * Created by Programacion on 31/07/2015. */ public class Frm_principal extends Fragment { TextView tv_funcion,tv_descripcion; ImageView img_principal; ListView listview_principal; ArrayAdapter<Principal> adapter; Principal dato; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.layout_frm_principal,container,false); inicializarComponentesUi(rootView); inicializarListaContactos(); inicializarDatosLista(); listview_principal.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if(position==0) { Fragment newFragment = new Frm_Cliente(); FragmentTransaction asd = getActivity().getSupportFragmentManager().beginTransaction(); asd.replace(R.layout.layout_frm_principal,) } } }); return(rootView); } private void inicializarDatosLista() { Principal nuevo = new Principal("Cliente","Añadir modificar o anular clientes",getResources().getDrawable(R.drawable.ic_cliente)); adapter.add(nuevo); } private void inicializarListaContactos() { adapter = new PrincipalAdapter(getActivity(),new ArrayList<Principal>()); listview_principal.setAdapter(adapter); } private void inicializarComponentesUi(final View view) { tv_funcion = (TextView)view.findViewById(R.id.tv_funcion); tv_descripcion = (TextView)view.findViewById(R.id.tv_descripcion); img_principal =(ImageView)view.findViewById(R.id.img_principal); listview_principal =(ListView)view.findViewById(R.id.listview_principal); } } ` 仅在第一个记录中查找记录。我99%肯定这个错误在于我如何编写这个承诺链,而不是在被调用的函数中。

这里是按预期工作的块。

 package com.example.programacion.ventasje.Cliente;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.example.programacion.ventasje.R;


/**
 * Created by Programacion on 30/07/2015.
 */
public class Frm_Cliente extends Fragment {




    private TextView tvCliente,tvCentro,tvOficio,tvLocalidad;


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.layout_frmcliente,container,false);
        inicializarComponentesUi(rootView);
        return(rootView);
    }


    private void inicializarComponentesUi(final View view) {
        tvCliente = (TextView)view.findViewById(R.id.tv_cliente);
        tvCentro = (TextView)view.findViewById(R.id.tv_centro);
        tvOficio = (TextView)view.findViewById(R.id.tv_oficio);
        tvLocalidad = (TextView)view.findViewById(R.id.tv_localidad);


}

}

此代码添加了两个语句,但在isCrawlDue内,找不到两个语句。我知道clearStatements() .then(dbFinancials.addStatement("XYZ", "type", moment.utc([2014, 0, 31]), 3, "none") .then(function (added1) { assert.isTrue(added1, "First record not added."); dbFinancials.addStatement("XYZ", "type", moment.utc(), 4, "none") .then(function (added2) { assert.isTrue(added2, "Second record not added."); dataCollection.isCrawlDue("XYZ") .then(function (isDue) { assert.isTrue(isDue, "No need for a crawl detected."); done(); }); }); })); 有效,因为它适用于上面的代码。

isCrawlDue

任何人都可以看到我做错了吗?

2 个答案:

答案 0 :(得分:0)

请改为尝试:

clearStatements()
.then(dbFinancials.addStatement("XYZ", "type", moment.utc([2014, 0, 31]), 3, "none"))
.then(dbFinancials.addStatement("XYZ", "type", moment.utc(), 4, "none"))
.then(dataCollection.isCrawlDue("XYZ"))
.then(function (isDue) {
    assert.isTrue(isDue, "No need for a crawl detected.");
    done();
});

我在dataCollection.isCrawlDue("XYZ")后面添加了第二个结束括号,并将其从末尾删除,因此.then仅包装dataCollection.isCrawlDue("XYZ")

.then返回一个值并期望另一个承诺,而不是一系列承诺。

答案 1 :(得分:0)

  

.then(dbFinancials.addStatement(&#34; XYZ&#34;,&#34; type&#34;,moment.utc([2014,0,31]),3,&#34; none&#34 ;))

不正确使用承诺。 .then接受一个函数(将在解析先前的promise时调用),而是调用addStatement函数,并将结果作为参数提供给.then
因此,在第一个示例中,有一个错误,即addStatement之后立即调用clearStatements(),而不是等待它解决。链的其余部分工作正常。

在第二个示例中,正如@apsillers clearStatements绝对正确指出的那样,两个addStatementisCrawlDue被一个接一个地调用,而无需等待解决。显然,addStatement还没有推送isCrawlDue尚未找到的任何信息。

要以适当的方式重写它,您应该在函数中包装addStatements或使用bind(因为bind实际上返回一个函数)。我将在下面的代码段中使用这些不同的方式来演示我的意思

clearStatements()
.then(function(){
    return dbFinancials.addStatement("XYZ", "type", moment.utc([2014, 0, 31]), 3, "none")
})
.then(dbFinancials.addStatement.bind(dbFinancials, "XYZ", "type", moment.utc(), 4, "none"))
.then(function(){
    return dataCollection.isCrawlDue("XYZ");
})
.then(function (isDue) {
    assert.isTrue(isDue, "No need for a crawl detected.");
    done();
});

在这两种情况下,对addStatement的呼叫将被延迟,直到上一个操作得到解决。 isCrawlDue将在第二个addStatement解决后执行

希望这有帮助